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.

1220 lines
21 KiB

  1. //
  2. // Copyright (c) 1998-1999, Microsoft Corporation, all rights reserved
  3. //
  4. // util.c
  5. //
  6. // IEEE1394 mini-port/call-manager driver
  7. //
  8. // General utility routines
  9. //
  10. // 12/28/1998 JosephJ Created, adapted from the l2tp sources.
  11. //
  12. #include "precomp.h"
  13. // Debug counts of oddities that should not be happening.
  14. //
  15. ULONG g_ulAllocTwFailures = 0;
  16. //-----------------------------------------------------------------------------
  17. // Local prototypes (alphabetically)
  18. //-----------------------------------------------------------------------------
  19. ULONG
  20. atoul(
  21. IN CHAR* pszNumber );
  22. VOID
  23. ReversePsz(
  24. IN OUT CHAR* psz );
  25. VOID
  26. TunnelWork(
  27. IN NDIS_WORK_ITEM* pWork,
  28. IN VOID* pContext );
  29. VOID
  30. ultoa(
  31. IN ULONG ul,
  32. OUT CHAR* pszBuf );
  33. //-----------------------------------------------------------------------------
  34. // General utility routines (alphabetically)
  35. //-----------------------------------------------------------------------------
  36. CHAR*
  37. nicStrDup(
  38. IN CHAR* psz )
  39. // Return a duplicate of 'psz'. Caller must eventually call FREE_NONPAGED
  40. // on the returned string.
  41. //
  42. {
  43. return nicStrDupSized( psz, strlen( psz ), 0 );
  44. }
  45. CHAR*
  46. nicStrDupNdisString(
  47. IN NDIS_STRING* pNdisString )
  48. // Returns null-terminated ASCII copy of the NDIS_STRING 'pNdisString'
  49. // Caller must eventually call FREE_NONPAGED on the returned string.
  50. //
  51. {
  52. CHAR* pszDup;
  53. pszDup = ALLOC_NONPAGED( pNdisString->Length + 1, MTAG_UTIL );
  54. if (pszDup)
  55. {
  56. NdisZeroMemory( pszDup, pNdisString->Length + 1 );
  57. if (pNdisString->Length)
  58. {
  59. NdisMoveMemory( pszDup, pNdisString->Buffer, pNdisString->Length );
  60. }
  61. // NDIS_STRING is UNICODE_STRING on NT but need the corresponding
  62. // ASCII (not multi-byte ANSI) value from NDIS_STRING on any system.
  63. // If it looks like a Unicode string then "convert" it by picking out
  64. // every other byte, hopefully all the non-zero ones. This is not
  65. // foolproof, but then Unicode doesn't convert to ASCII in any
  66. // foolproof way.
  67. //
  68. if (pNdisString->Length > 1 && pszDup[ 1 ] == '\0')
  69. {
  70. USHORT i;
  71. for (i = 0; i * 2 < pNdisString->Length; ++i)
  72. {
  73. pszDup[ i ] = pszDup[ i * 2 ];
  74. }
  75. pszDup[ i ] = '\0';
  76. }
  77. }
  78. return pszDup;
  79. }
  80. CHAR*
  81. nicStrDupSized(
  82. IN CHAR* psz,
  83. IN ULONG ulLength,
  84. IN ULONG ulExtra )
  85. // Return a duplicate of the first 'ulLength' bytes of 'psz' followed by a
  86. // null character and 'ulExtra' extra bytes, or NULL on error. Caller
  87. // must eventually call FREE_NONPAGED on the returned string.
  88. //
  89. {
  90. CHAR* pszDup;
  91. pszDup = ALLOC_NONPAGED( ulLength + 1 + ulExtra, MTAG_UTIL );
  92. if (pszDup)
  93. {
  94. if (ulLength)
  95. {
  96. NdisMoveMemory( pszDup, psz, ulLength );
  97. }
  98. pszDup[ ulLength ] = '\0';
  99. }
  100. return pszDup;
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Local utility routines (alphabetically)
  104. //-----------------------------------------------------------------------------
  105. ULONG
  106. atoul(
  107. IN CHAR* pszNumber )
  108. // Convert string of digits 'pszNumber' to it's ULONG value.
  109. //
  110. {
  111. ULONG ulResult;
  112. ulResult = 0;
  113. while (*pszNumber && *pszNumber >= '0' && *pszNumber <= '9')
  114. {
  115. ulResult *= 10;
  116. ulResult += *pszNumber - '0';
  117. ++pszNumber;
  118. }
  119. return ulResult;
  120. }
  121. #if DBG
  122. VOID
  123. ReversePsz(
  124. IN OUT CHAR* psz )
  125. // Reverse the order of the characters in 'psz' in place.
  126. //
  127. {
  128. CHAR* pchLeft;
  129. CHAR* pchRight;
  130. pchLeft = psz;
  131. pchRight = psz + strlen( psz ) - 1;
  132. while (pchLeft < pchRight)
  133. {
  134. CHAR ch;
  135. ch = *pchLeft;
  136. *pchLeft = *pchRight;
  137. *pchRight = *pchLeft;
  138. ++pchLeft;
  139. --pchRight;
  140. }
  141. }
  142. #endif
  143. #if DBG
  144. VOID
  145. ultoa(
  146. IN ULONG ul,
  147. OUT CHAR* pszBuf )
  148. // Convert 'ul' to null-terminated string form in caller's 'pszBuf'. It's
  149. // caller job to make sure 'pszBuf' is long enough to hold the returned
  150. // string.
  151. //
  152. {
  153. CHAR* pch;
  154. pch = pszBuf;
  155. do
  156. {
  157. *pch++ = (CHAR )((ul % 10) + '0');
  158. ul /= 10;
  159. }
  160. while (ul);
  161. *pch = '\0';
  162. ReversePsz( pszBuf );
  163. }
  164. #endif
  165. VOID
  166. nicSetFlags(
  167. IN OUT ULONG* pulFlags,
  168. IN ULONG ulMask )
  169. // Set 'ulMask' bits in '*pulFlags' flags as an interlocked operation.
  170. //
  171. {
  172. ULONG ulFlags;
  173. ULONG ulNewFlags;
  174. do
  175. {
  176. ulFlags = *pulFlags;
  177. ulNewFlags = ulFlags | ulMask;
  178. }
  179. while (InterlockedCompareExchange(
  180. pulFlags, ulNewFlags, ulFlags ) != (LONG )ulFlags);
  181. }
  182. VOID
  183. nicClearFlags(
  184. IN OUT ULONG* pulFlags,
  185. IN ULONG ulMask )
  186. // Set 'ulMask' bits in '*pulFlags' flags as an interlocked operation.
  187. //
  188. {
  189. ULONG ulFlags;
  190. ULONG ulNewFlags;
  191. do
  192. {
  193. ulFlags = *pulFlags;
  194. ulNewFlags = ulFlags & ~(ulMask);
  195. }
  196. while (InterlockedCompareExchange(
  197. pulFlags, ulNewFlags, ulFlags ) != (LONG )ulFlags);
  198. }
  199. ULONG
  200. nicReadFlags(
  201. IN ULONG* pulFlags )
  202. // Read the value of '*pulFlags' as an interlocked operation.
  203. //
  204. {
  205. return *pulFlags;
  206. }
  207. //
  208. // Reference And Dereference functions taken directly from Ndis
  209. //
  210. BOOLEAN
  211. nicReferenceRef(
  212. IN PREF RefP
  213. )
  214. /*++
  215. Routine Description:
  216. Adds a reference to an object.
  217. Arguments:
  218. RefP - A pointer to the REFERENCE portion of the object.
  219. Return Value:
  220. TRUE if the reference was added.
  221. FALSE if the object was closing.
  222. --*/
  223. {
  224. BOOLEAN rc = TRUE;
  225. KIRQL OldIrql;
  226. TRACE( TL_V, TM_Ref, ( "nicReferenceRef, %.8x", RefP ) );
  227. // NdisAcquireSpinLock (&RefP->SpinLock);
  228. if (RefP->Closing)
  229. {
  230. rc = FALSE;
  231. }
  232. else
  233. {
  234. NdisInterlockedIncrement (&RefP->ReferenceCount);
  235. }
  236. // NdisReleaseSpinLock (&RefP->SpinLock);
  237. TRACE( TL_V, TM_Ref, ( "nicReferenceRef, Bool %.2x, Ref %d", rc, RefP->ReferenceCount ) );
  238. return(rc);
  239. }
  240. BOOLEAN
  241. nicDereferenceRef(
  242. IN PREF RefP
  243. )
  244. /*++
  245. Routine Description:
  246. Removes a reference to an object.
  247. Arguments:
  248. RefP - A pointer to the REFERENCE portion of the object.
  249. Return Value:
  250. TRUE if the reference count is now 0.
  251. FALSE otherwise.
  252. --*/
  253. {
  254. BOOLEAN rc = FALSE;
  255. KIRQL OldIrql;
  256. TRACE( TL_V, TM_Ref, ( "==>nicDeReferenceRef, %x", RefP ) );
  257. // NdisAcquireSpinLock (&RefP->SpinLock);
  258. NdisInterlockedDecrement (&RefP->ReferenceCount);
  259. if (RefP->ReferenceCount == 0)
  260. {
  261. rc = TRUE;
  262. NdisSetEvent (&RefP->RefZeroEvent);
  263. }
  264. if ((signed long)RefP->ReferenceCount < 0)
  265. {
  266. ASSERT ( !"Ref Has Gone BELOW ZERO");
  267. }
  268. // NdisReleaseSpinLock (&RefP->SpinLock);
  269. TRACE( TL_V, TM_Ref, ( "<==nicDeReferenceRef, %.2x, RefCount %d", rc, RefP->ReferenceCount ) );
  270. return(rc);
  271. }
  272. VOID
  273. nicInitializeRef(
  274. IN PREF RefP
  275. )
  276. /*++
  277. Routine Description:
  278. Initialize a reference count structure.
  279. Arguments:
  280. RefP - The structure to be initialized.
  281. Return Value:
  282. None.
  283. --*/
  284. {
  285. TRACE( TL_V, TM_Ref, ( "==>nicInitializeRef, %.8x", RefP ) );
  286. RefP->Closing = FALSE;
  287. RefP->ReferenceCount = 1;
  288. // NdisAllocateSpinLock (&RefP->SpinLock);
  289. NdisInitializeEvent (&RefP->RefZeroEvent);
  290. TRACE( TL_V, TM_Ref, ( "<==nicInitializeRef, %.8x", RefP ) );
  291. }
  292. BOOLEAN
  293. nicCloseRef(
  294. IN PREF RefP
  295. )
  296. /*++
  297. Routine Description:
  298. Closes a reference count structure.
  299. Arguments:
  300. RefP - The structure to be closed.
  301. Return Value:
  302. FALSE if it was already closing.
  303. TRUE otherwise.
  304. --*/
  305. {
  306. KIRQL OldIrql;
  307. BOOLEAN rc = TRUE;
  308. TRACE( TL_N, TM_Ref, ( "==>ndisCloseRef, %.8x", RefP ) );
  309. // NdisAcquireSpinLock (&RefP->SpinLock);
  310. if (RefP->Closing)
  311. {
  312. rc = FALSE;
  313. }
  314. else RefP->Closing = TRUE;
  315. // NdisReleaseSpinLock (&RefP->SpinLock);
  316. TRACE( TL_N, TM_Ref, ( "<==ndisCloseRef, %.8x, RefCount %.8x", RefP, RefP->ReferenceCount ) );
  317. return(rc);
  318. }
  319. //
  320. //
  321. // These are self expanatory Pdo Reference functions
  322. // which will be turned into macros once we have functionality
  323. // working
  324. //
  325. BOOLEAN
  326. nicReferenceRemoteNode (
  327. IN REMOTE_NODE *pPdoCb,
  328. IN PCHAR pDebugPrint
  329. )
  330. /*++
  331. Routine Description:
  332. Arguments:
  333. Return Value:
  334. --*/
  335. {
  336. BOOLEAN bRefClosing = FALSE;
  337. bRefClosing = nicReferenceRef (&pPdoCb->Ref);
  338. TRACE( TL_V, TM_RemRef, ( "**nicReferenceRemoteNode pPdoCb %x, to %d, %s, ret %x ",
  339. pPdoCb, pPdoCb->Ref.ReferenceCount, pDebugPrint, bRefClosing ) );
  340. return bRefClosing ;
  341. }
  342. BOOLEAN
  343. nicDereferenceRemoteNode (
  344. IN REMOTE_NODE *pPdoCb,
  345. IN PCHAR pDebugPrint
  346. )
  347. /*++
  348. Routine Description:
  349. Arguments:
  350. Return Value:
  351. --*/
  352. {
  353. TRACE( TL_V, TM_RemRef, ( "**nicDereferenceRemoteNode %x to %d , %s",
  354. pPdoCb , pPdoCb->Ref.ReferenceCount -1, pDebugPrint ) );
  355. return nicDereferenceRef (&pPdoCb->Ref);
  356. }
  357. VOID
  358. nicInitalizeRefRemoteNode(
  359. IN REMOTE_NODE *pPdoCb
  360. )
  361. /*++
  362. Routine Description:
  363. Closes Ref on the remote node
  364. Arguments:
  365. IN REMOTE_NODE *pPdoCb - RemoteNode
  366. Return Value:
  367. None
  368. --*/
  369. {
  370. TRACE( TL_N, TM_Ref, ( "**nicinitalizeRefPdoCb pPdoCb %.8x", pPdoCb ) );
  371. nicInitializeRef (&pPdoCb->Ref);
  372. }
  373. BOOLEAN
  374. nicCloseRefRemoteNode(
  375. IN REMOTE_NODE *pPdoCb
  376. )
  377. /*++
  378. Routine Description:
  379. Closes Ref on the remote node
  380. Arguments:
  381. IN REMOTE_NODE *pPdoCb - RemoteNode
  382. Return Value:
  383. Return value of nicCloseRef
  384. --*/
  385. {
  386. TRACE( TL_N, TM_Ref, ( "**nicClosePdoCb pPdoCb %.8x", pPdoCb ) );
  387. return nicCloseRef (&pPdoCb->Ref);
  388. }
  389. NDIS_STATUS
  390. NtStatusToNdisStatus (
  391. NTSTATUS NtStatus
  392. )
  393. /*++
  394. Routine Description:
  395. Dumps the packet , if the appropriate Debuglevels are set
  396. Arguments:
  397. NTSTATUS NtStatus - NtStatus to be converted
  398. Return Value:
  399. NdisStatus - NtStatus' corresponding NdisStatus
  400. --*/
  401. {
  402. NDIS_STATUS NdisStatus;
  403. switch (NtStatus)
  404. {
  405. case STATUS_SUCCESS:
  406. {
  407. NdisStatus = NDIS_STATUS_SUCCESS;
  408. break;
  409. }
  410. case STATUS_UNSUCCESSFUL:
  411. {
  412. NdisStatus = NDIS_STATUS_FAILURE;
  413. break;
  414. }
  415. case STATUS_PENDING:
  416. {
  417. NdisStatus = NDIS_STATUS_PENDING;
  418. break;
  419. }
  420. case STATUS_INVALID_BUFFER_SIZE:
  421. {
  422. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  423. break;
  424. }
  425. case STATUS_INSUFFICIENT_RESOURCES:
  426. {
  427. NdisStatus = NDIS_STATUS_RESOURCES;
  428. break;
  429. }
  430. case STATUS_INVALID_GENERATION:
  431. {
  432. NdisStatus = NDIS_STATUS_DEST_OUT_OF_ORDER;
  433. break;
  434. }
  435. case STATUS_ALREADY_COMMITTED:
  436. {
  437. NdisStatus = NDIS_STATUS_RESOURCE_CONFLICT;
  438. break;
  439. }
  440. case STATUS_DEVICE_BUSY:
  441. {
  442. NdisStatus = NDIS_STATUS_MEDIA_BUSY;
  443. break;
  444. }
  445. case STATUS_INVALID_PARAMETER:
  446. {
  447. NdisStatus = NDIS_STATUS_INVALID_DATA;
  448. break;
  449. }
  450. case STATUS_DEVICE_DATA_ERROR:
  451. {
  452. NdisStatus = NDIS_STATUS_DEST_OUT_OF_ORDER;
  453. break;
  454. }
  455. case STATUS_TIMEOUT:
  456. {
  457. NdisStatus = NDIS_STATUS_FAILURE;
  458. break;
  459. }
  460. case STATUS_IO_DEVICE_ERROR:
  461. {
  462. NdisStatus = NDIS_STATUS_NETWORK_UNREACHABLE;
  463. break;
  464. }
  465. default:
  466. {
  467. NdisStatus = NDIS_STATUS_FAILURE;
  468. TRACE( TL_A, TM_Send, ( "Cause: Don't know, INVESTIGATE %x", NtStatus ) );
  469. //ASSERT (0);
  470. }
  471. }
  472. return NdisStatus;
  473. }
  474. VOID
  475. PrintNdisPacket (
  476. ULONG TM_Comp,
  477. PNDIS_PACKET pMyPacket
  478. )
  479. /*++
  480. Routine Description:
  481. Dumps the packet , if the appropriate Debuglevels are set
  482. Arguments:
  483. ULONG TM_Comp = Debug Component
  484. PNDIS_PACKET pMyPacket - Packet to be printed
  485. Return Value:
  486. None
  487. --*/
  488. {
  489. PNDIS_BUFFER pPrintNdisBuffer = pMyPacket->Private.Head;
  490. //
  491. // Print out the complete NdisPacket . Change to DEBUG ONLY
  492. //
  493. while (pPrintNdisBuffer != NULL)
  494. {
  495. PVOID pPrintData = NdisBufferVirtualAddress(pPrintNdisBuffer);
  496. ULONG PrintLength = NdisBufferLength (pPrintNdisBuffer);
  497. TRACE( TL_D, TM_Comp, ( " pNdisbuffer %x, pData %x, Len %x", pPrintNdisBuffer, pPrintData, PrintLength) );
  498. if (pPrintData != NULL)
  499. {
  500. DUMPB (TL_D, TM_Recv, pPrintData, PrintLength);
  501. }
  502. pPrintNdisBuffer = pPrintNdisBuffer->Next;
  503. }
  504. }
  505. VOID
  506. nicAllocatePacket(
  507. OUT PNDIS_STATUS pNdisStatus,
  508. OUT PNDIS_PACKET *ppNdisPacket,
  509. IN PNIC_PACKET_POOL pPacketPool
  510. )
  511. /*++
  512. Routine Description:
  513. Calls the ndis API to allocate a packet. On Win9X calls to allocate packets are serialized
  514. Arguments:
  515. pNdisStatus - pointer to NdisStatus
  516. *ppNdisPacket - Ndis packet Allocated by Ndis,
  517. pPacketPool - packet pool from which the packet is allocated
  518. Return Value:
  519. return value of the call to Ndis
  520. --*/
  521. {
  522. KIRQL OldIrql;
  523. #ifdef Win9X
  524. #if PACKETPOOL_LOCK
  525. KeAcquireSpinLock(&pPacketPool->Lock, &OldIrql);
  526. #endif
  527. #endif
  528. NdisAllocatePacket (pNdisStatus,
  529. ppNdisPacket,
  530. pPacketPool->Handle );
  531. #ifdef Win9X
  532. #if PACKETPOOL_LOCK
  533. KeReleaseSpinLock(&pPacketPool->Lock, OldIrql);
  534. #endif
  535. #endif
  536. if (*pNdisStatus == NDIS_STATUS_SUCCESS)
  537. {
  538. PRSVD pRsvd = NULL;
  539. PINDICATE_RSVD pIndicateRsvd = NULL;
  540. pRsvd =(PRSVD)((*ppNdisPacket)->ProtocolReserved);
  541. pIndicateRsvd = &pRsvd->IndicateRsvd;
  542. pIndicateRsvd->Tag = NIC1394_TAG_ALLOCATED;
  543. NdisInterlockedIncrement (&pPacketPool->AllocatedPackets);
  544. }
  545. else
  546. {
  547. *ppNdisPacket = NULL;
  548. nicIncrementMallocFailure();
  549. }
  550. }
  551. VOID
  552. nicFreePacket(
  553. IN PNDIS_PACKET pNdisPacket,
  554. IN PNIC_PACKET_POOL pPacketPool
  555. )
  556. /*++
  557. Routine Description:
  558. Free the packet and decrements the outstanding Packet count.
  559. All calls are serialized on Win9x
  560. Arguments:
  561. IN PNDIS_PACKET pNdisPacket - Packet to be freed
  562. IN PNIC_PACKET_POOL pPacketPool - PacketPool to which the packet belongs
  563. Return Value:
  564. None
  565. --*/
  566. {
  567. KIRQL OldIrql;
  568. PRSVD pRsvd = NULL;
  569. PINDICATE_RSVD pIndicateRsvd = NULL;
  570. pRsvd =(PRSVD)(pNdisPacket->ProtocolReserved);
  571. pIndicateRsvd = &pRsvd->IndicateRsvd;
  572. pIndicateRsvd->Tag = NIC1394_TAG_FREED;
  573. #ifdef Win9X
  574. #if PACKETPOOL_LOCK
  575. KeAcquireSpinLock(&pPacketPool->Lock, &OldIrql);
  576. #endif
  577. #endif
  578. NdisInterlockedDecrement (&pPacketPool->AllocatedPackets);
  579. NdisFreePacket (pNdisPacket);
  580. #ifdef Win9X
  581. #if PACKETPOOL_LOCK
  582. KeReleaseSpinLock(&pPacketPool->Lock, OldIrql);
  583. #endif
  584. #endif
  585. }
  586. VOID
  587. nicFreePacketPool (
  588. IN PNIC_PACKET_POOL pPacketPool
  589. )
  590. /*++
  591. Routine Description:
  592. frees the packet pool after waiting for the outstanding packet count to go to zero
  593. Arguments:
  594. IN PNIC_PACKET_POOL pPacketPool - PacketPool which is to be freed
  595. Return Value:
  596. None
  597. --*/
  598. {
  599. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  600. while (NdisPacketPoolUsage (pPacketPool->Handle)!=0)
  601. {
  602. TRACE( TL_V, TM_Cm, ( " Waiting PacketPool %x, AllocatedPackets %x",
  603. pPacketPool->Handle, pPacketPool->AllocatedPackets ) );
  604. NdisMSleep (10000);
  605. }
  606. NdisFreePacketPool (pPacketPool->Handle);
  607. pPacketPool->Handle = NULL;
  608. ASSERT (pPacketPool->AllocatedPackets == 0);
  609. }
  610. VOID
  611. nicAcquireSpinLock (
  612. IN PNIC_SPIN_LOCK pNicSpinLock,
  613. IN PUCHAR FileName,
  614. IN UINT LineNumber
  615. )
  616. /*++
  617. Routine Description:
  618. Acquires a spin lock and if the Dbg, then it will spew out the line and file
  619. Arguments:
  620. NIC_SPIN_LOCK - Lock to be acquired
  621. Return Value:
  622. None
  623. --*/
  624. {
  625. PKTHREAD pThread;
  626. TRACE (TL_V, TM_Lock, ("Lock %x, Acquired by File %s, Line %x" , pNicSpinLock, FileName, LineNumber)) ;
  627. NdisAcquireSpinLock(&(pNicSpinLock->NdisLock));
  628. #if TRACK_LOCKS
  629. pThread = KeGetCurrentThread();
  630. pNicSpinLock->OwnerThread = pThread;
  631. NdisMoveMemory(pNicSpinLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN);
  632. pNicSpinLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0;
  633. pNicSpinLock->TouchedInLineNumber = LineNumber;
  634. pNicSpinLock->IsAcquired++;
  635. #endif
  636. }
  637. VOID
  638. nicReleaseSpinLock (
  639. IN PNIC_SPIN_LOCK pNicSpinLock,
  640. IN PUCHAR FileName,
  641. IN UINT LineNumber
  642. )
  643. /*++
  644. Routine Description:
  645. Release a spin lock and if Dbg is On, then it will spew out the line and file
  646. Arguments:
  647. pNicSpinLock - Lock to be Release
  648. FileName - File Name
  649. LineNumber - Line
  650. Return Value:
  651. None
  652. --*/
  653. {
  654. PKTHREAD pThread;
  655. TRACE (TL_V, TM_Lock, ("Lock %x, Released by File %s, Line %x" , pNicSpinLock, FileName, LineNumber)) ;
  656. #if TRACK_LOCKS
  657. pThread = KeGetCurrentThread();
  658. NdisMoveMemory(pNicSpinLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN);
  659. pNicSpinLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0;
  660. pNicSpinLock->TouchedInLineNumber = LineNumber;
  661. pNicSpinLock->IsAcquired--;
  662. pNicSpinLock->OwnerThread = 0;
  663. #endif
  664. NdisReleaseSpinLock(&(pNicSpinLock->NdisLock));
  665. }
  666. VOID
  667. nicInitializeNicSpinLock (
  668. IN PNIC_SPIN_LOCK pNicSpinLock
  669. )
  670. /*++
  671. Routine Description:
  672. Initializes the lock in the SpinLock
  673. Arguments:
  674. pNicSpinLock - SpinLock
  675. Return Value:
  676. None
  677. --*/
  678. {
  679. NdisAllocateSpinLock (&pNicSpinLock->NdisLock);
  680. }
  681. VOID
  682. nicFreeNicSpinLock (
  683. IN PNIC_SPIN_LOCK pNicSpinLock
  684. )
  685. /*++
  686. Routine Description:
  687. Frees the spinlock
  688. Arguments:
  689. pNicSpinLock - SpinLock
  690. Return Value:
  691. None
  692. --*/
  693. {
  694. ASSERT ((ULONG)pNicSpinLock->NdisLock.SpinLock == 0);
  695. NdisFreeSpinLock (&pNicSpinLock->NdisLock);
  696. }
  697. UINT
  698. nicGetSystemTime(
  699. VOID
  700. )
  701. /*++
  702. Returns system time in seconds.
  703. Since it's in seconds, we won't overflow unless the system has been up
  704. for over
  705. a 100 years :-)
  706. --*/
  707. {
  708. LARGE_INTEGER Time;
  709. NdisGetCurrentSystemTime(&Time);
  710. Time.QuadPart /= 10000000; //100-nanoseconds to seconds.
  711. return Time.LowPart;
  712. }
  713. UINT
  714. nicGetSystemTimeMilliSeconds(
  715. VOID
  716. )
  717. /*++
  718. Returns system time in seconds.
  719. Since it's in seconds, we won't overflow unless the system has been up
  720. for over
  721. a 100 years :-)
  722. --*/
  723. {
  724. LARGE_INTEGER Time;
  725. NdisGetCurrentSystemTime(&Time);
  726. Time.QuadPart /= 10000; //10-nanoseconds to seconds.
  727. return Time.LowPart;
  728. }
  729. ULONG
  730. SwapBytesUlong(
  731. IN ULONG Val)
  732. {
  733. return ((((Val) & 0x000000ff) << 24) | (((Val) & 0x0000ff00) << 8) | (((Val) & 0x00ff0000) >> 8) | (((Val) & 0xff000000) >> 24) );
  734. }
  735. void
  736. nicTimeStamp(
  737. char *szFormatString,
  738. UINT Val
  739. )
  740. /*++
  741. Routine Description:
  742. Execute and print a time stamp
  743. Arguments:
  744. Return Value:
  745. --*/
  746. {
  747. UINT Minutes;
  748. UINT Seconds;
  749. UINT Milliseconds;
  750. LARGE_INTEGER Time;
  751. NdisGetCurrentSystemTime(&Time);
  752. Time.QuadPart /= 10000; //10-nanoseconds to milliseconds.
  753. Milliseconds = Time.LowPart; // don't care about highpart.
  754. Seconds = Milliseconds/1000;
  755. Milliseconds %= 1000;
  756. Minutes = Seconds/60;
  757. Seconds %= 60;
  758. DbgPrint( szFormatString, Minutes, Seconds, Milliseconds, Val);
  759. }
  760. VOID
  761. nicDumpPkt (
  762. IN PNDIS_PACKET pPacket,
  763. CHAR * str
  764. )
  765. {
  766. PNDIS_BUFFER pBuffer;
  767. extern BOOLEAN g_ulNicDumpPacket ;
  768. if ( g_ulNicDumpPacket == FALSE)
  769. {
  770. return ;
  771. }
  772. pBuffer = pPacket->Private.Head;
  773. DbgPrint (str);
  774. DbgPrint ("Packet %p TotLen %x", pPacket, pPacket->Private.TotalLength);
  775. do
  776. {
  777. ULONG Length = nicNdisBufferLength (pBuffer);
  778. PUCHAR pVa = nicNdisBufferVirtualAddress (pBuffer);
  779. DbgPrint ("pBuffer %p, Len %x \n", pBuffer, Length);
  780. Dump( pVa, Length, 0, 1 );
  781. pBuffer = pBuffer->Next;
  782. } while (pBuffer != NULL);
  783. }
  784. VOID
  785. nicDumpMdl (
  786. IN PMDL pMdl,
  787. IN ULONG LengthToPrint,
  788. IN CHAR *str
  789. )
  790. {
  791. ULONG MdlLength ;
  792. PUCHAR pVa;
  793. extern BOOLEAN g_ulNicDumpPacket ;
  794. if ( g_ulNicDumpPacket == FALSE )
  795. {
  796. return;
  797. }
  798. MdlLength = MmGetMdlByteCount(pMdl);
  799. //
  800. // if Length is zero then use MdlLength
  801. //
  802. if (LengthToPrint == 0)
  803. {
  804. LengthToPrint = MdlLength;
  805. }
  806. //
  807. // Check for invalid length
  808. //
  809. if (MdlLength < LengthToPrint)
  810. {
  811. return;
  812. }
  813. pVa = MmGetSystemAddressForMdlSafe(pMdl,LowPagePriority );
  814. if (pVa == NULL)
  815. {
  816. return;
  817. }
  818. DbgPrint (str);
  819. DbgPrint ("pMdl %p, Len %x\n", pMdl, LengthToPrint);
  820. Dump( pVa, LengthToPrint, 0, 1 );
  821. }