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.

396 lines
8.0 KiB

  1. // Copyright (c) 1997, Microsoft Corporation, all rights reserved
  2. // Copyright (c) 1997, Parallel Technologies, Inc., all rights reserved
  3. //
  4. // util.c
  5. // DirectParallel WAN mini-port/call-manager driver
  6. // General utility routines
  7. //
  8. // 01/07/97 Steve Cobb
  9. // 09/15/97 Jay Lowe, Parallel Technologies, Inc.
  10. #include "ptiwan.h"
  11. //-----------------------------------------------------------------------------
  12. // Local prototypes (alphabetically)
  13. //-----------------------------------------------------------------------------
  14. ULONG
  15. atoul(
  16. IN CHAR* pszNumber );
  17. VOID
  18. ReversePsz(
  19. IN OUT CHAR* psz );
  20. VOID
  21. ultoa(
  22. IN ULONG ul,
  23. OUT CHAR* pszBuf );
  24. //-----------------------------------------------------------------------------
  25. // General utility routines (alphabetically)
  26. //-----------------------------------------------------------------------------
  27. VOID
  28. ClearFlags(
  29. IN OUT ULONG* pulFlags,
  30. IN ULONG ulMask )
  31. // Set 'ulMask' bits in '*pulFlags' flags as an interlocked operation.
  32. //
  33. {
  34. ULONG ulFlags;
  35. ULONG ulNewFlags;
  36. do
  37. {
  38. ulFlags = ReadFlags( pulFlags );
  39. ulNewFlags = ulFlags & ~(ulMask);
  40. }
  41. while (InterlockedCompareExchange(
  42. pulFlags, ulNewFlags, ulFlags ) != (LONG)ulFlags);
  43. }
  44. VOID
  45. IndicateLinkStatus(
  46. IN VCCB* pVc )
  47. // Indicate new WAN_CO_LINKPARAMS settings for 'pVc' to NDISWAN.
  48. //
  49. {
  50. ADAPTERCB* pAdapter;
  51. WAN_CO_LINKPARAMS params;
  52. pAdapter = pVc->pAdapter;
  53. params.TransmitSpeed = pVc->ulConnectBps;
  54. params.ReceiveSpeed = params.TransmitSpeed;
  55. params.SendWindow = 1;
  56. TRACE( TL_N, TM_Mp, ( "NdisMCoIndStatus(LINK) cid=%d bps=%d sw=%d",
  57. pVc->usCallId, params.TransmitSpeed, params.SendWindow ) );
  58. NdisMCoIndicateStatus(
  59. pAdapter->MiniportAdapterHandle,
  60. pVc->NdisVcHandle,
  61. NDIS_STATUS_WAN_CO_LINKPARAMS,
  62. &params,
  63. sizeof(params) );
  64. TRACE( TL_N, TM_Mp, ( "NdisMCoIndStatus done" ) );
  65. }
  66. ULONG
  67. ReadFlags(
  68. IN ULONG* pulFlags )
  69. // Read the value of '*pulFlags' as an interlocked operation.
  70. //
  71. {
  72. return InterlockedExchangeAdd( pulFlags, 0 );
  73. }
  74. NDIS_STATUS
  75. ScheduleWork(
  76. IN ADAPTERCB* pAdapter,
  77. IN NDIS_PROC pProc,
  78. IN PVOID pContext )
  79. // Schedules a PASSIVE IRQL callback to routine 'pProc' which will be
  80. // passed 'pContext'. 'PAdapter' is the adapter control block from which
  81. // the work item is allocated. This routine takes an adapter reference
  82. // that should be removed by the called 'pProc'.
  83. //
  84. // Returns NDIS_STATUS_SUCCESS or an error code.
  85. //
  86. {
  87. NDIS_STATUS status;
  88. NDIS_WORK_ITEM* pWork;
  89. pWork = ALLOC_NDIS_WORK_ITEM( pAdapter );
  90. if (!pWork)
  91. {
  92. ASSERT( !"Alloc work?" );
  93. return NDIS_STATUS_RESOURCES;
  94. }
  95. NdisInitializeWorkItem( pWork, pProc, pContext );
  96. ReferenceAdapter( pAdapter );
  97. status = NdisScheduleWorkItem( pWork );
  98. if (status != NDIS_STATUS_SUCCESS)
  99. {
  100. ASSERT( !"SchedWork?" );
  101. FREE_NDIS_WORK_ITEM( pAdapter, pWork );
  102. DereferenceAdapter( pAdapter );
  103. }
  104. return status;
  105. }
  106. VOID
  107. SetFlags(
  108. IN OUT ULONG* pulFlags,
  109. IN ULONG ulMask )
  110. // Set 'ulMask' bits in '*pulFlags' flags as an interlocked operation.
  111. //
  112. {
  113. ULONG ulFlags;
  114. ULONG ulNewFlags;
  115. do
  116. {
  117. ulFlags = ReadFlags( pulFlags );
  118. ulNewFlags = ulFlags | ulMask;
  119. }
  120. while (InterlockedCompareExchange(
  121. pulFlags, ulNewFlags, ulFlags ) != (LONG )ulFlags);
  122. }
  123. ULONG
  124. StrCmp(
  125. IN LPSTR cs,
  126. IN LPSTR ct,
  127. ULONG n
  128. )
  129. // Return 0 if string cs = string ct for length n
  130. //
  131. {
  132. char ret=0;
  133. while (n--)
  134. {
  135. ret = *cs - *ct;
  136. if (ret)
  137. break;
  138. cs++;
  139. ct++;
  140. }
  141. return (ULONG)ret;
  142. }
  143. ULONG
  144. StrCmpW(
  145. IN WCHAR* psz1,
  146. IN WCHAR* psz2 )
  147. // Returns 0 if 'psz1' matches 'psz2'.
  148. //
  149. {
  150. WCHAR pch;
  151. pch = (WCHAR )0;
  152. while (*psz1 && *psz2)
  153. {
  154. pch = *psz1 - *psz2;
  155. if (pch)
  156. {
  157. break;
  158. }
  159. psz1++;
  160. psz2++;
  161. }
  162. return (ULONG )pch;
  163. }
  164. VOID
  165. StrCpyW(
  166. IN WCHAR* psz1,
  167. IN WCHAR* psz2 )
  168. // Copies 'psz2' to 'psz1'.
  169. //
  170. {
  171. while (*psz2)
  172. {
  173. *psz1++ = *psz2++;
  174. }
  175. *psz1 = L'\0';
  176. }
  177. CHAR*
  178. StrDup(
  179. IN CHAR* psz )
  180. // Return a duplicate of 'psz'. Caller must eventually call FREE_NONPAGED
  181. // on the returned string.
  182. //
  183. {
  184. return StrDupSized( psz, strlen( psz ), 0 );
  185. }
  186. CHAR*
  187. StrDupNdisString(
  188. IN NDIS_STRING* pNdisString )
  189. // Returns null-terminated ASCII copy of the NDIS_STRING 'pNdisString'
  190. // Caller must eventually call FREE_NONPAGED on the returned string.
  191. //
  192. {
  193. CHAR* pszDup;
  194. pszDup = ALLOC_NONPAGED( pNdisString->Length + 1, MTAG_UTIL );
  195. if (pszDup)
  196. {
  197. NdisZeroMemory( pszDup, pNdisString->Length + 1 );
  198. if (pNdisString->Length)
  199. {
  200. NdisMoveMemory( pszDup, pNdisString->Buffer, pNdisString->Length );
  201. }
  202. // NDIS_STRING is UNICODE_STRING on NT but need the corresponding
  203. // ASCII (not multi-byte ANSI) value from NDIS_STRING on any system.
  204. // If it looks like a Unicode string then "convert" it by picking out
  205. // every other byte, hopefully all the non-zero ones. This is not
  206. // foolproof, but then Unicode doesn't convert to ASCII in any
  207. // foolproof way.
  208. //
  209. if (pNdisString->Length > 1 && pszDup[ 1 ] == '\0')
  210. {
  211. USHORT i;
  212. for (i = 0; i * 2 < pNdisString->Length; ++i)
  213. {
  214. pszDup[ i ] = pszDup[ i * 2 ];
  215. }
  216. pszDup[ i ] = '\0';
  217. }
  218. }
  219. return pszDup;
  220. }
  221. CHAR*
  222. StrDupSized(
  223. IN CHAR* psz,
  224. IN ULONG ulLength,
  225. IN ULONG ulExtra )
  226. // Return a duplicate of the first 'ulLength' bytes of 'psz' followed by a
  227. // null character and 'ulExtra' extra bytes, or NULL on error. Caller
  228. // must eventually call FREE_NONPAGED on the returned string.
  229. //
  230. {
  231. CHAR* pszDup;
  232. pszDup = ALLOC_NONPAGED( ulLength + 1 + ulExtra, MTAG_UTIL );
  233. if (pszDup)
  234. {
  235. if (ulLength)
  236. {
  237. NdisMoveMemory( pszDup, psz, ulLength );
  238. }
  239. pszDup[ ulLength ] = '\0';
  240. }
  241. return pszDup;
  242. }
  243. ULONG
  244. StrLenW(
  245. IN WCHAR* psz )
  246. // Returns number of characters in a null-terminated Unicode string.
  247. //
  248. {
  249. ULONG ul;
  250. ul = 0;
  251. while (*psz++)
  252. {
  253. ++ul;
  254. }
  255. return ul;
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Local utility routines (alphabetically)
  259. //-----------------------------------------------------------------------------
  260. ULONG
  261. atoul(
  262. IN CHAR* pszNumber )
  263. // Convert string of digits 'pszNumber' to it's ULONG value.
  264. //
  265. {
  266. ULONG ulResult;
  267. ulResult = 0;
  268. while (*pszNumber && *pszNumber >= '0' && *pszNumber <= '9')
  269. {
  270. ulResult *= 10;
  271. ulResult += *pszNumber - '0';
  272. ++pszNumber;
  273. }
  274. return ulResult;
  275. }
  276. VOID
  277. ReversePsz(
  278. IN OUT CHAR* psz )
  279. // Reverse the order of the characters in 'psz' in place.
  280. //
  281. {
  282. CHAR* pchLeft;
  283. CHAR* pchRight;
  284. pchLeft = psz;
  285. pchRight = psz + strlen( psz ) - 1;
  286. while (pchLeft < pchRight)
  287. {
  288. CHAR ch;
  289. ch = *pchLeft;
  290. *pchLeft = *pchRight;
  291. *pchRight = *pchLeft;
  292. }
  293. }
  294. #if 0
  295. VOID
  296. ultoa(
  297. IN ULONG ul,
  298. OUT CHAR* pszBuf )
  299. // Convert 'ul' to null-terminated string form in caller's 'pszBuf'.
  300. //
  301. {
  302. CHAR* pch;
  303. pch = pszBuf;
  304. do
  305. {
  306. *pch++ = (CHAR )((ul % 10) + '0');
  307. ul /= 10;
  308. }
  309. while (ul);
  310. *pch = '\0';
  311. ReversePsz( pszBuf );
  312. }
  313. #endif