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.

864 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. miniport.c
  5. Abstract:
  6. NDIS wrapper functions
  7. Author:
  8. Sean Selitrennikoff (SeanSe) 05-Oct-93
  9. Jameel Hyder (JameelH) Re-organization 01-Jun-95
  10. Environment:
  11. Kernel mode, FSD
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. //
  17. // Define the module number for debug code.
  18. //
  19. #define MODULE_NUMBER MODULE_MINISUB
  20. VOID
  21. NdisAllocateSpinLock(
  22. IN PNDIS_SPIN_LOCK SpinLock
  23. )
  24. {
  25. INITIALIZE_SPIN_LOCK(&SpinLock->SpinLock);
  26. }
  27. VOID
  28. NdisFreeSpinLock(
  29. IN PNDIS_SPIN_LOCK SpinLock
  30. )
  31. {
  32. UNREFERENCED_PARAMETER(SpinLock);
  33. }
  34. VOID
  35. NdisAcquireSpinLock(
  36. IN PNDIS_SPIN_LOCK SpinLock
  37. )
  38. {
  39. NDIS_ACQUIRE_SPIN_LOCK(SpinLock, &SpinLock->OldIrql);
  40. }
  41. VOID
  42. NdisReleaseSpinLock(
  43. IN PNDIS_SPIN_LOCK SpinLock
  44. )
  45. {
  46. NDIS_RELEASE_SPIN_LOCK(SpinLock, SpinLock->OldIrql);
  47. }
  48. VOID
  49. NdisDprAcquireSpinLock(
  50. IN PNDIS_SPIN_LOCK SpinLock
  51. )
  52. {
  53. NDIS_ACQUIRE_SPIN_LOCK_DPC(SpinLock);
  54. SpinLock->OldIrql = DISPATCH_LEVEL;
  55. }
  56. VOID
  57. NdisDprReleaseSpinLock(
  58. IN PNDIS_SPIN_LOCK SpinLock
  59. )
  60. {
  61. NDIS_RELEASE_SPIN_LOCK_DPC(SpinLock);
  62. }
  63. #undef NdisFreeBuffer
  64. VOID
  65. NdisFreeBuffer(
  66. IN PNDIS_BUFFER Buffer
  67. )
  68. {
  69. IoFreeMdl(Buffer);
  70. }
  71. #undef NdisQueryBuffer
  72. VOID
  73. NdisQueryBuffer(
  74. IN PNDIS_BUFFER Buffer,
  75. OUT PVOID * VirtualAddress OPTIONAL,
  76. OUT PUINT Length
  77. )
  78. {
  79. if (ARGUMENT_PRESENT(VirtualAddress))
  80. {
  81. *VirtualAddress = MDL_ADDRESS(Buffer);
  82. }
  83. *Length = MDL_SIZE(Buffer);
  84. }
  85. VOID
  86. NdisQueryBufferSafe(
  87. IN PNDIS_BUFFER Buffer,
  88. OUT PVOID * VirtualAddress OPTIONAL,
  89. OUT PUINT Length,
  90. IN MM_PAGE_PRIORITY Priority
  91. )
  92. {
  93. if (ARGUMENT_PRESENT(VirtualAddress))
  94. {
  95. *VirtualAddress = MDL_ADDRESS_SAFE(Buffer, Priority);
  96. }
  97. *Length = MDL_SIZE(Buffer);
  98. }
  99. VOID
  100. NdisQueryBufferOffset(
  101. IN PNDIS_BUFFER Buffer,
  102. OUT PUINT Offset,
  103. OUT PUINT Length
  104. )
  105. {
  106. *Offset = MDL_OFFSET(Buffer);
  107. *Length = MDL_SIZE(Buffer);
  108. }
  109. VOID
  110. NdisGetFirstBufferFromPacket(
  111. IN PNDIS_PACKET Packet,
  112. OUT PNDIS_BUFFER * FirstBuffer,
  113. OUT PVOID * FirstBufferVA,
  114. OUT PUINT FirstBufferLength,
  115. OUT PUINT TotalBufferLength
  116. )
  117. {
  118. PNDIS_BUFFER pBuf;
  119. pBuf = Packet->Private.Head;
  120. *FirstBuffer = pBuf;
  121. if (pBuf)
  122. {
  123. *FirstBufferVA = MmGetSystemAddressForMdl(pBuf);
  124. *FirstBufferLength = *TotalBufferLength = MmGetMdlByteCount(pBuf);
  125. for (pBuf = pBuf->Next;
  126. pBuf != NULL;
  127. pBuf = pBuf->Next)
  128. {
  129. *TotalBufferLength += MmGetMdlByteCount(pBuf);
  130. }
  131. }
  132. else
  133. {
  134. *FirstBufferVA = 0;
  135. *FirstBufferLength = 0;
  136. *TotalBufferLength = 0;
  137. }
  138. }
  139. //
  140. // safe version of NdisGetFirstBufferFromPacket
  141. // if the memory described by the first buffer can not be mapped
  142. // this function will return NULL for FirstBuferVA
  143. //
  144. VOID
  145. NdisGetFirstBufferFromPacketSafe(
  146. IN PNDIS_PACKET Packet,
  147. OUT PNDIS_BUFFER * FirstBuffer,
  148. OUT PVOID * FirstBufferVA,
  149. OUT PUINT FirstBufferLength,
  150. OUT PUINT TotalBufferLength,
  151. IN MM_PAGE_PRIORITY Priority
  152. )
  153. {
  154. PNDIS_BUFFER pBuf;
  155. pBuf = Packet->Private.Head;
  156. *FirstBuffer = pBuf;
  157. if (pBuf)
  158. {
  159. *FirstBufferVA = MmGetSystemAddressForMdlSafe(pBuf, Priority);
  160. *FirstBufferLength = *TotalBufferLength = MmGetMdlByteCount(pBuf);
  161. for (pBuf = pBuf->Next;
  162. pBuf != NULL;
  163. pBuf = pBuf->Next)
  164. {
  165. *TotalBufferLength += MmGetMdlByteCount(pBuf);
  166. }
  167. }
  168. else
  169. {
  170. *FirstBufferVA = 0;
  171. *FirstBufferLength = 0;
  172. *TotalBufferLength = 0;
  173. }
  174. }
  175. ULONG
  176. NdisBufferLength(
  177. IN PNDIS_BUFFER Buffer
  178. )
  179. {
  180. return (MmGetMdlByteCount(Buffer));
  181. }
  182. PVOID
  183. NdisBufferVirtualAddress(
  184. IN PNDIS_BUFFER Buffer
  185. )
  186. {
  187. return (MDL_ADDRESS_SAFE(Buffer, HighPagePriority));
  188. }
  189. ULONG
  190. NDIS_BUFFER_TO_SPAN_PAGES(
  191. IN PNDIS_BUFFER Buffer
  192. )
  193. {
  194. if (MDL_SIZE(Buffer) == 0)
  195. {
  196. return 1;
  197. }
  198. return ADDRESS_AND_SIZE_TO_SPAN_PAGES(MDL_VA(Buffer), MDL_SIZE(Buffer));
  199. }
  200. VOID
  201. NdisGetBufferPhysicalArraySize(
  202. IN PNDIS_BUFFER Buffer,
  203. OUT PUINT ArraySize
  204. )
  205. {
  206. if (MDL_SIZE(Buffer) == 0)
  207. {
  208. *ArraySize = 1;
  209. }
  210. else
  211. {
  212. *ArraySize = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MDL_VA(Buffer), MDL_SIZE(Buffer));
  213. }
  214. }
  215. NDIS_STATUS
  216. NdisAnsiStringToUnicodeString(
  217. IN OUT PUNICODE_STRING DestinationString,
  218. IN PANSI_STRING SourceString
  219. )
  220. {
  221. NDIS_STATUS Status;
  222. Status = RtlAnsiStringToUnicodeString(DestinationString,
  223. SourceString,
  224. FALSE);
  225. return Status;
  226. }
  227. NDIS_STATUS
  228. NdisUnicodeStringToAnsiString(
  229. IN OUT PANSI_STRING DestinationString,
  230. IN PUNICODE_STRING SourceString
  231. )
  232. {
  233. NDIS_STATUS Status;
  234. Status = RtlUnicodeStringToAnsiString(DestinationString,
  235. SourceString,
  236. FALSE);
  237. return Status;
  238. }
  239. NDIS_STATUS
  240. NdisUpcaseUnicodeString(
  241. OUT PUNICODE_STRING DestinationString,
  242. IN PUNICODE_STRING SourceString
  243. )
  244. {
  245. return(RtlUpcaseUnicodeString(DestinationString, SourceString, FALSE));
  246. }
  247. VOID
  248. NdisMStartBufferPhysicalMapping(
  249. IN NDIS_HANDLE MiniportAdapterHandle,
  250. IN PNDIS_BUFFER Buffer,
  251. IN ULONG PhysicalMapRegister,
  252. IN BOOLEAN WriteToDevice,
  253. OUT PNDIS_PHYSICAL_ADDRESS_UNIT PhysicalAddressArray,
  254. OUT PUINT ArraySize
  255. )
  256. {
  257. NdisMStartBufferPhysicalMappingMacro(MiniportAdapterHandle,
  258. Buffer,
  259. PhysicalMapRegister,
  260. WriteToDevice,
  261. PhysicalAddressArray,
  262. ArraySize);
  263. }
  264. VOID
  265. NdisMCompleteBufferPhysicalMapping(
  266. IN NDIS_HANDLE MiniportAdapterHandle,
  267. IN PNDIS_BUFFER Buffer,
  268. IN ULONG PhysicalMapRegister
  269. )
  270. {
  271. NdisMCompleteBufferPhysicalMappingMacro(MiniportAdapterHandle,
  272. Buffer,
  273. PhysicalMapRegister);
  274. }
  275. #undef NdisInterlockedIncrement
  276. LONG
  277. NdisInterlockedIncrement(
  278. IN PLONG Addend
  279. )
  280. {
  281. return(InterlockedIncrement(Addend));
  282. }
  283. #undef NdisInterlockedDecrement
  284. LONG
  285. NdisInterlockedDecrement(
  286. IN PLONG Addend
  287. )
  288. {
  289. return(InterlockedDecrement(Addend));
  290. }
  291. #undef NdisInterlockedAddUlong
  292. ULONG
  293. NdisInterlockedAddUlong(
  294. IN PULONG Addend,
  295. IN ULONG Increment,
  296. IN PNDIS_SPIN_LOCK SpinLock
  297. )
  298. {
  299. return(ExInterlockedAddUlong(Addend,Increment, &SpinLock->SpinLock));
  300. }
  301. #undef NdisInterlockedInsertHeadList
  302. PLIST_ENTRY
  303. NdisInterlockedInsertHeadList(
  304. IN PLIST_ENTRY ListHead,
  305. IN PLIST_ENTRY ListEntry,
  306. IN PNDIS_SPIN_LOCK SpinLock
  307. )
  308. {
  309. return(ExInterlockedInsertHeadList(ListHead,ListEntry,&SpinLock->SpinLock));
  310. }
  311. #undef NdisInterlockedInsertTailList
  312. PLIST_ENTRY
  313. NdisInterlockedInsertTailList(
  314. IN PLIST_ENTRY ListHead,
  315. IN PLIST_ENTRY ListEntry,
  316. IN PNDIS_SPIN_LOCK SpinLock
  317. )
  318. {
  319. return(ExInterlockedInsertTailList(ListHead,ListEntry,&SpinLock->SpinLock));
  320. }
  321. #undef NdisInterlockedRemoveHeadList
  322. PLIST_ENTRY
  323. NdisInterlockedRemoveHeadList(
  324. IN PLIST_ENTRY ListHead,
  325. IN PNDIS_SPIN_LOCK SpinLock
  326. )
  327. {
  328. return(ExInterlockedRemoveHeadList(ListHead, &SpinLock->SpinLock));
  329. }
  330. #undef NdisInterlockedPushEntryList
  331. PSINGLE_LIST_ENTRY
  332. NdisInterlockedPushEntryList(
  333. IN PSINGLE_LIST_ENTRY ListHead,
  334. IN PSINGLE_LIST_ENTRY ListEntry,
  335. IN PNDIS_SPIN_LOCK Lock
  336. )
  337. {
  338. return(ExInterlockedPushEntryList(ListHead, ListEntry, &Lock->SpinLock));
  339. }
  340. #undef NdisInterlockedPopEntryList
  341. PSINGLE_LIST_ENTRY
  342. NdisInterlockedPopEntryList(
  343. IN PSINGLE_LIST_ENTRY ListHead,
  344. IN PNDIS_SPIN_LOCK Lock
  345. )
  346. {
  347. return(ExInterlockedPopEntryList(ListHead, &Lock->SpinLock));
  348. }
  349. //
  350. // Logging support for miniports
  351. //
  352. NDIS_STATUS
  353. NdisMCreateLog(
  354. IN NDIS_HANDLE MiniportAdapterHandle,
  355. IN UINT Size,
  356. OUT PNDIS_HANDLE LogHandle
  357. )
  358. {
  359. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)MiniportAdapterHandle;
  360. PNDIS_LOG Log = NULL;
  361. NDIS_STATUS Status;
  362. KIRQL OldIrql;
  363. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  364. if (Miniport->Log != NULL)
  365. {
  366. Status = NDIS_STATUS_FAILURE;
  367. }
  368. else
  369. {
  370. Log = ALLOC_FROM_POOL(sizeof(NDIS_LOG) + Size, NDIS_TAG_DBG_LOG);
  371. if (Log != NULL)
  372. {
  373. Status = NDIS_STATUS_SUCCESS;
  374. Miniport->Log = Log;
  375. INITIALIZE_SPIN_LOCK(&Log->LogLock);
  376. Log->Miniport = Miniport;
  377. Log->Irp = NULL;
  378. Log->TotalSize = Size;
  379. Log->CurrentSize = 0;
  380. Log->InPtr = 0;
  381. Log->OutPtr = 0;
  382. }
  383. else
  384. {
  385. Status = NDIS_STATUS_RESOURCES;
  386. }
  387. }
  388. *LogHandle = Log;
  389. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  390. return Status;
  391. }
  392. VOID
  393. NdisMCloseLog(
  394. IN NDIS_HANDLE LogHandle
  395. )
  396. {
  397. PNDIS_LOG Log = (PNDIS_LOG)LogHandle;
  398. PNDIS_MINIPORT_BLOCK Miniport;
  399. KIRQL OldIrql;
  400. Miniport = Log->Miniport;
  401. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK(Miniport, &OldIrql);
  402. Miniport->Log = NULL;
  403. NDIS_RELEASE_MINIPORT_SPIN_LOCK(Miniport, OldIrql);
  404. FREE_POOL(Log);
  405. }
  406. NDIS_STATUS
  407. NdisMWriteLogData(
  408. IN NDIS_HANDLE LogHandle,
  409. IN PVOID LogBuffer,
  410. IN UINT LogBufferSize
  411. )
  412. {
  413. PNDIS_LOG Log = (PNDIS_LOG)LogHandle;
  414. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  415. KIRQL OldIrql;
  416. UINT AmtToCopy;
  417. //1 should we limit drivers to how much they can log?
  418. IoAcquireCancelSpinLock(&OldIrql);
  419. ACQUIRE_SPIN_LOCK_DPC(&Log->LogLock);
  420. if (LogBufferSize <= Log->TotalSize)
  421. {
  422. if (LogBufferSize <= (Log->TotalSize - Log->InPtr))
  423. {
  424. //
  425. // Can copy the entire buffer
  426. //
  427. CopyMemory(Log->LogBuf+Log->InPtr, LogBuffer, LogBufferSize);
  428. }
  429. else
  430. {
  431. //
  432. // We are going to wrap around. Copy it in two chunks.
  433. //
  434. AmtToCopy = Log->TotalSize - Log->InPtr;
  435. CopyMemory(Log->LogBuf+Log->InPtr,
  436. LogBuffer,
  437. AmtToCopy);
  438. CopyMemory(Log->LogBuf + 0,
  439. (PUCHAR)LogBuffer+AmtToCopy,
  440. LogBufferSize - AmtToCopy);
  441. }
  442. //
  443. // Update the current size
  444. //
  445. Log->CurrentSize += LogBufferSize;
  446. if (Log->CurrentSize > Log->TotalSize)
  447. Log->CurrentSize = Log->TotalSize;
  448. //
  449. // Update the InPtr and possibly the outptr
  450. //
  451. Log->InPtr += LogBufferSize;
  452. if (Log->InPtr >= Log->TotalSize)
  453. {
  454. Log->InPtr -= Log->TotalSize;
  455. }
  456. if (Log->CurrentSize == Log->TotalSize)
  457. {
  458. Log->OutPtr = Log->InPtr;
  459. }
  460. //
  461. // Check if there is a pending Irp to complete
  462. //
  463. if (Log->Irp != NULL)
  464. {
  465. PIRP Irp = Log->Irp;
  466. PUCHAR Buffer;
  467. Log->Irp = NULL;
  468. //
  469. // If the InPtr is lagging the OutPtr. then we can simply
  470. // copy the data over in one shot.
  471. //
  472. AmtToCopy = MDL_SIZE(Irp->MdlAddress);
  473. if (AmtToCopy > Log->CurrentSize)
  474. AmtToCopy = Log->CurrentSize;
  475. if ((Log->TotalSize - Log->OutPtr) >= AmtToCopy)
  476. {
  477. Buffer = MDL_ADDRESS_SAFE(Irp->MdlAddress, LowPagePriority);
  478. if (Buffer != NULL)
  479. {
  480. CopyMemory(Buffer,
  481. Log->LogBuf+Log->OutPtr,
  482. AmtToCopy);
  483. }
  484. else Status = NDIS_STATUS_RESOURCES;
  485. }
  486. else
  487. {
  488. Buffer = MDL_ADDRESS_SAFE(Irp->MdlAddress, LowPagePriority);
  489. if (Buffer != NULL)
  490. {
  491. CopyMemory(Buffer,
  492. Log->LogBuf+Log->OutPtr,
  493. Log->TotalSize-Log->OutPtr);
  494. CopyMemory(Buffer+Log->TotalSize-Log->OutPtr,
  495. Log->LogBuf,
  496. AmtToCopy - (Log->TotalSize-Log->OutPtr));
  497. }
  498. else Status = NDIS_STATUS_RESOURCES;
  499. }
  500. Log->CurrentSize -= AmtToCopy;
  501. Log->OutPtr += AmtToCopy;
  502. if (Log->OutPtr >= Log->TotalSize)
  503. Log->OutPtr -= Log->TotalSize;
  504. Irp->IoStatus.Information = AmtToCopy;
  505. //1 can we do this without IoAcquireCancelSpinLock?
  506. IoSetCancelRoutine(Irp, NULL);
  507. Irp->IoStatus.Status = STATUS_SUCCESS;
  508. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  509. }
  510. }
  511. else
  512. {
  513. Status = NDIS_STATUS_BUFFER_OVERFLOW;
  514. }
  515. RELEASE_SPIN_LOCK_DPC(&Log->LogLock);
  516. IoReleaseCancelSpinLock(OldIrql);
  517. return Status;
  518. }
  519. NDIS_STATUS
  520. FASTCALL
  521. ndisMGetLogData(
  522. IN PNDIS_MINIPORT_BLOCK Miniport,
  523. IN PIRP Irp
  524. )
  525. {
  526. NTSTATUS Status = STATUS_SUCCESS;
  527. KIRQL OldIrql;
  528. PNDIS_LOG Log;
  529. UINT AmtToCopy;
  530. IoAcquireCancelSpinLock(&OldIrql);
  531. NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  532. if ((Log = Miniport->Log) != NULL)
  533. {
  534. ACQUIRE_SPIN_LOCK_DPC(&Log->LogLock);
  535. if (Log->CurrentSize != 0)
  536. {
  537. PUCHAR Buffer;
  538. //
  539. // If the InPtr is lagging the OutPtr. then we can simply
  540. // copy the data over in one shot.
  541. //
  542. AmtToCopy = MDL_SIZE(Irp->MdlAddress);
  543. if (AmtToCopy > Log->CurrentSize)
  544. AmtToCopy = Log->CurrentSize;
  545. Buffer = MDL_ADDRESS_SAFE(Irp->MdlAddress, LowPagePriority);
  546. if (Buffer != NULL)
  547. {
  548. if ((Log->TotalSize - Log->OutPtr) >= AmtToCopy)
  549. {
  550. CopyMemory(Buffer,
  551. Log->LogBuf+Log->OutPtr,
  552. AmtToCopy);
  553. }
  554. else
  555. {
  556. CopyMemory(Buffer,
  557. Log->LogBuf+Log->OutPtr,
  558. Log->TotalSize-Log->OutPtr);
  559. CopyMemory(Buffer+Log->TotalSize-Log->OutPtr,
  560. Log->LogBuf,
  561. AmtToCopy - (Log->TotalSize-Log->OutPtr));
  562. }
  563. Log->CurrentSize -= AmtToCopy;
  564. Log->OutPtr += AmtToCopy;
  565. if (Log->OutPtr >= Log->TotalSize)
  566. Log->OutPtr -= Log->TotalSize;
  567. Irp->IoStatus.Information = AmtToCopy;
  568. Status = STATUS_SUCCESS;
  569. }
  570. else
  571. {
  572. Status = STATUS_INSUFFICIENT_RESOURCES;
  573. }
  574. }
  575. else if (Log->Irp != NULL)
  576. {
  577. Status = STATUS_UNSUCCESSFUL;
  578. }
  579. else
  580. {
  581. IoSetCancelRoutine(Irp, ndisCancelLogIrp);
  582. Log->Irp = Irp;
  583. Status = STATUS_PENDING;
  584. }
  585. RELEASE_SPIN_LOCK_DPC(&Log->LogLock);
  586. }
  587. else
  588. {
  589. Status = STATUS_UNSUCCESSFUL;
  590. }
  591. NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
  592. IoReleaseCancelSpinLock(OldIrql);
  593. return Status;
  594. }
  595. VOID
  596. NdisMFlushLog(
  597. IN NDIS_HANDLE LogHandle
  598. )
  599. {
  600. PNDIS_LOG Log = (PNDIS_LOG)LogHandle;
  601. KIRQL OldIrql;
  602. ACQUIRE_SPIN_LOCK(&Log->LogLock, &OldIrql);
  603. Log->InPtr = 0;
  604. Log->OutPtr = 0;
  605. Log->CurrentSize = 0;
  606. RELEASE_SPIN_LOCK(&Log->LogLock, OldIrql);
  607. }
  608. NDIS_STATUS
  609. NdisMQueryAdapterInstanceName(
  610. OUT PNDIS_STRING pAdapterInstanceName,
  611. IN NDIS_HANDLE NdisAdapterHandle
  612. )
  613. {
  614. PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)NdisAdapterHandle;
  615. USHORT cbSize;
  616. PVOID ptmp = NULL;
  617. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  618. NTSTATUS NtStatus;
  619. DBGPRINT(DBG_COMP_CONFIG, DBG_LEVEL_INFO,
  620. ("==>NdisMQueryAdapterInstanceName\n"));
  621. //
  622. // If we failed to create the adapter instance name then fail this call.
  623. //
  624. if (NULL != Miniport->pAdapterInstanceName)
  625. {
  626. //
  627. // Allocate storage for the copy of the adapter instance name.
  628. //
  629. cbSize = Miniport->pAdapterInstanceName->MaximumLength;
  630. //
  631. // Allocate storage for the new string.
  632. //
  633. ptmp = ALLOC_FROM_POOL(cbSize, NDIS_TAG_NAME_BUF);
  634. if (NULL != ptmp)
  635. {
  636. RtlZeroMemory(ptmp, cbSize);
  637. pAdapterInstanceName->Buffer = ptmp;
  638. pAdapterInstanceName->Length = 0;
  639. pAdapterInstanceName->MaximumLength = cbSize;
  640. NtStatus = RtlAppendUnicodeStringToString(
  641. pAdapterInstanceName,
  642. Miniport->pAdapterInstanceName);
  643. if (NT_SUCCESS(NtStatus))
  644. {
  645. Status = NDIS_STATUS_SUCCESS;
  646. }
  647. }
  648. else
  649. {
  650. Status = NDIS_STATUS_RESOURCES;
  651. }
  652. }
  653. if (NDIS_STATUS_SUCCESS != Status)
  654. {
  655. if (NULL != ptmp)
  656. {
  657. FREE_POOL(ptmp);
  658. }
  659. }
  660. DBGPRINT(DBG_COMP_CONFIG, DBG_LEVEL_INFO,
  661. ("<==NdisMQueryAdapterInstanceName: 0x%x\n", Status));
  662. return(Status);
  663. }
  664. EXPORT
  665. VOID
  666. NdisInitializeReadWriteLock(
  667. IN PNDIS_RW_LOCK Lock
  668. )
  669. {
  670. NdisZeroMemory(Lock, sizeof(NDIS_RW_LOCK));
  671. }
  672. VOID
  673. NdisAcquireReadWriteLock(
  674. IN PNDIS_RW_LOCK Lock,
  675. IN BOOLEAN fWrite,
  676. IN PLOCK_STATE LockState
  677. )
  678. {
  679. if (fWrite)
  680. {
  681. LockState->LockState = WRITE_LOCK_STATE_UNKNOWN;
  682. {
  683. UINT i, refcount;
  684. ULONG Prc;
  685. /*
  686. * This means we need to attempt to acquire the lock,
  687. * if we do not already own it.
  688. * Set the state accordingly.
  689. */
  690. if ((Lock)->Context == CURRENT_THREAD)
  691. {
  692. (LockState)->LockState = LOCK_STATE_ALREADY_ACQUIRED;
  693. }
  694. else
  695. {
  696. ACQUIRE_SPIN_LOCK(&(Lock)->SpinLock, &(LockState)->OldIrql);
  697. Prc = KeGetCurrentProcessorNumber();
  698. refcount = (Lock)->RefCount[Prc].RefCount;
  699. (Lock)->RefCount[Prc].RefCount = 0;
  700. /* wait for all readers to exit */
  701. for (i=0; i < ndisNumberOfProcessors; i++)
  702. {
  703. volatile UINT *_p = &(Lock)->RefCount[i].RefCount;
  704. while (*_p != 0)
  705. NDIS_INTERNAL_STALL(50);
  706. }
  707. (Lock)->RefCount[Prc].RefCount = refcount;
  708. (Lock)->Context = CURRENT_THREAD;
  709. (LockState)->LockState = WRITE_LOCK_STATE_FREE;
  710. }
  711. }
  712. }
  713. else
  714. {
  715. LockState->LockState = READ_LOCK;
  716. {
  717. LONG refcount;
  718. ULONG Prc;
  719. RAISE_IRQL_TO_DISPATCH(&(LockState)->OldIrql);
  720. /* go ahead and bump up the ref count IF no writes are underway */
  721. Prc = CURRENT_PROCESSOR;
  722. refcount = InterlockedIncrement((PLONG)&Lock->RefCount[Prc].RefCount);
  723. /* Test if spin lock is held, i.e., write is underway */
  724. /* if (KeTestSpinLock(&(_L)->SpinLock) == TRUE) */
  725. /* This processor already is holding the lock, just */
  726. /* allow him to take it again or else we run into a */
  727. /* dead-lock situation with the writer */
  728. if (TEST_SPIN_LOCK((Lock)->SpinLock) &&
  729. (refcount == 1) &&
  730. ((Lock)->Context != CURRENT_THREAD))
  731. {
  732. (Lock)->RefCount[Prc].RefCount--;
  733. ACQUIRE_SPIN_LOCK_DPC(&(Lock)->SpinLock);
  734. (Lock)->RefCount[Prc].RefCount++;
  735. RELEASE_SPIN_LOCK_DPC(&(Lock)->SpinLock);
  736. }
  737. (LockState)->LockState = READ_LOCK_STATE_FREE;
  738. }
  739. }
  740. }
  741. VOID
  742. NdisReleaseReadWriteLock(
  743. IN PNDIS_RW_LOCK Lock,
  744. IN PLOCK_STATE LockState
  745. )
  746. {
  747. xLockHandler(Lock, LockState);
  748. }