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.

1114 lines
38 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. rtutils.h
  5. Abstract:
  6. Public declarations for the Router process utility functions.
  7. --*/
  8. #ifndef __ROUTING_RTUTILS_H__
  9. #define __ROUTING_RTUTILS_H__
  10. #if _MSC_VER > 1000
  11. #pragma once
  12. #endif
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. //////////////////////////////////////////////////////////////////////////////
  17. // //
  18. // TRACING FUNCTION PROTOTYPES //
  19. // //
  20. // See DOCUMENT for more information //
  21. // //
  22. //////////////////////////////////////////////////////////////////////////////
  23. //////////////////////////////////////////////////////////////////////////////
  24. // //
  25. // Definitions for flags and constants //
  26. // //
  27. //////////////////////////////////////////////////////////////////////////////
  28. #define TRACE_USE_FILE 0x00000001
  29. #define TRACE_USE_CONSOLE 0x00000002
  30. #define TRACE_NO_SYNCH 0x00000004
  31. #define TRACE_NO_STDINFO 0x00000001
  32. #define TRACE_USE_MASK 0x00000002
  33. #define TRACE_USE_MSEC 0x00000004
  34. #define TRACE_USE_DATE 0x00000008
  35. #define INVALID_TRACEID 0xFFFFFFFF
  36. //////////////////////////////////////////////////////////////////////////////
  37. // //
  38. // ANSI entry-points //
  39. // //
  40. //////////////////////////////////////////////////////////////////////////////
  41. DWORD
  42. APIENTRY
  43. TraceRegisterExA(
  44. IN LPCSTR lpszCallerName,
  45. IN DWORD dwFlags
  46. );
  47. DWORD
  48. APIENTRY
  49. TraceDeregisterA(
  50. IN DWORD dwTraceID
  51. );
  52. DWORD
  53. APIENTRY
  54. TraceDeregisterExA(
  55. IN DWORD dwTraceID,
  56. IN DWORD dwFlags
  57. );
  58. DWORD
  59. APIENTRY
  60. TraceGetConsoleA(
  61. IN DWORD dwTraceID,
  62. OUT LPHANDLE lphConsole
  63. );
  64. DWORD
  65. __cdecl
  66. TracePrintfA(
  67. IN DWORD dwTraceID,
  68. IN LPCSTR lpszFormat,
  69. IN ... OPTIONAL
  70. );
  71. DWORD
  72. __cdecl
  73. TracePrintfExA(
  74. IN DWORD dwTraceID,
  75. IN DWORD dwFlags,
  76. IN LPCSTR lpszFormat,
  77. IN ... OPTIONAL
  78. );
  79. DWORD
  80. APIENTRY
  81. TraceVprintfExA(
  82. IN DWORD dwTraceID,
  83. IN DWORD dwFlags,
  84. IN LPCSTR lpszFormat,
  85. IN va_list arglist
  86. );
  87. DWORD
  88. APIENTRY
  89. TracePutsExA(
  90. IN DWORD dwTraceID,
  91. IN DWORD dwFlags,
  92. IN LPCSTR lpszString
  93. );
  94. DWORD
  95. APIENTRY
  96. TraceDumpExA(
  97. IN DWORD dwTraceID,
  98. IN DWORD dwFlags,
  99. IN LPBYTE lpbBytes,
  100. IN DWORD dwByteCount,
  101. IN DWORD dwGroupSize,
  102. IN BOOL bAddressPrefix,
  103. IN LPCSTR lpszPrefix
  104. );
  105. //////////////////////////////////////////////////////////////////////////////
  106. // //
  107. // ANSI entry-points macros //
  108. // //
  109. //////////////////////////////////////////////////////////////////////////////
  110. #define TraceRegisterA(a) TraceRegisterExA(a,0)
  111. #define TraceVprintfA(a,b,c) TraceVprintfExA(a,0,b,c)
  112. #define TracePutsA(a,b) TracePutsExA(a,0,b)
  113. #define TraceDumpA(a,b,c,d,e,f) TraceDumpExA(a,0,b,c,d,e,f)
  114. //////////////////////////////////////////////////////////////////////////////
  115. // //
  116. // Unicode entry-points //
  117. // //
  118. //////////////////////////////////////////////////////////////////////////////
  119. DWORD
  120. APIENTRY
  121. TraceRegisterExW(
  122. IN LPCWSTR lpszCallerName,
  123. IN DWORD dwFlags
  124. );
  125. DWORD
  126. APIENTRY
  127. TraceDeregisterW(
  128. IN DWORD dwTraceID
  129. );
  130. DWORD
  131. APIENTRY
  132. TraceDeregisterExW(
  133. IN DWORD dwTraceID,
  134. IN DWORD dwFlags
  135. );
  136. DWORD
  137. APIENTRY
  138. TraceGetConsoleW(
  139. IN DWORD dwTraceID,
  140. OUT LPHANDLE lphConsole
  141. );
  142. DWORD
  143. __cdecl
  144. TracePrintfW(
  145. IN DWORD dwTraceID,
  146. IN LPCWSTR lpszFormat,
  147. IN ... OPTIONAL
  148. );
  149. DWORD
  150. __cdecl
  151. TracePrintfExW(
  152. IN DWORD dwTraceID,
  153. IN DWORD dwFlags,
  154. IN LPCWSTR lpszFormat,
  155. IN ... OPTIONAL
  156. );
  157. DWORD
  158. APIENTRY
  159. TraceVprintfExW(
  160. IN DWORD dwTraceID,
  161. IN DWORD dwFlags,
  162. IN LPCWSTR lpszFormat,
  163. IN va_list arglist
  164. );
  165. DWORD
  166. APIENTRY
  167. TracePutsExW(
  168. IN DWORD dwTraceID,
  169. IN DWORD dwFlags,
  170. IN LPCWSTR lpszString
  171. );
  172. DWORD
  173. APIENTRY
  174. TraceDumpExW(
  175. IN DWORD dwTraceID,
  176. IN DWORD dwFlags,
  177. IN LPBYTE lpbBytes,
  178. IN DWORD dwByteCount,
  179. IN DWORD dwGroupSize,
  180. IN BOOL bAddressPrefix,
  181. IN LPCWSTR lpszPrefix
  182. );
  183. //////////////////////////////////////////////////////////////////////////////
  184. // //
  185. // Unicode entry-points macros //
  186. // //
  187. //////////////////////////////////////////////////////////////////////////////
  188. #define TraceRegisterW(a) TraceRegisterExW(a,0)
  189. #define TraceVprintfW(a,b,c) TraceVprintfExW(a,0,b,c)
  190. #define TracePutsW(a,b) TracePutsExW(a,0,b)
  191. #define TraceDumpW(a,b,c,d,e,f) TraceDumpExW(a,0,b,c,d,e,f)
  192. //////////////////////////////////////////////////////////////////////////////
  193. // //
  194. // Code-page dependent entry-point macros //
  195. // //
  196. //////////////////////////////////////////////////////////////////////////////
  197. #ifdef UNICODE
  198. #define TraceRegister TraceRegisterW
  199. #define TraceDeregister TraceDeregisterW
  200. #define TraceDeregisterEx TraceDeregisterExW
  201. #define TraceGetConsole TraceGetConsoleW
  202. #define TracePrintf TracePrintfW
  203. #define TraceVprintf TraceVprintfW
  204. #define TracePuts TracePutsW
  205. #define TraceDump TraceDumpW
  206. #define TraceRegisterEx TraceRegisterExW
  207. #define TracePrintfEx TracePrintfExW
  208. #define TraceVprintfEx TraceVprintfExW
  209. #define TracePutsEx TracePutsExW
  210. #define TraceDumpEx TraceDumpExW
  211. #else
  212. #define TraceRegister TraceRegisterA
  213. #define TraceDeregister TraceDeregisterA
  214. #define TraceDeregisterEx TraceDeregisterExA
  215. #define TraceGetConsole TraceGetConsoleA
  216. #define TracePrintf TracePrintfA
  217. #define TraceVprintf TraceVprintfA
  218. #define TracePuts TracePutsA
  219. #define TraceDump TraceDumpA
  220. #define TraceRegisterEx TraceRegisterExA
  221. #define TracePrintfEx TracePrintfExA
  222. #define TraceVprintfEx TraceVprintfExA
  223. #define TracePutsEx TracePutsExA
  224. #define TraceDumpEx TraceDumpExA
  225. #endif
  226. //////////////////////////////////////////////////////////////////////////////
  227. // //
  228. // EVENT LOGGING FUNCTION PROTOTYPES //
  229. // //
  230. //////////////////////////////////////////////////////////////////////////////
  231. //////////////////////////////////////////////////////////////////////////////
  232. // //
  233. // ANSI prototypes //
  234. // //
  235. //////////////////////////////////////////////////////////////////////////////
  236. VOID
  237. APIENTRY
  238. LogErrorA(
  239. IN DWORD dwMessageId,
  240. IN DWORD cNumberOfSubStrings,
  241. IN LPSTR *plpwsSubStrings,
  242. IN DWORD dwErrorCode
  243. );
  244. VOID
  245. APIENTRY
  246. LogEventA(
  247. IN DWORD wEventType,
  248. IN DWORD dwMessageId,
  249. IN DWORD cNumberOfSubStrings,
  250. IN LPSTR *plpwsSubStrings
  251. );
  252. //////////////////////////////////////////////////////////////////////////////
  253. // //
  254. // Unicode prototypes //
  255. // //
  256. //////////////////////////////////////////////////////////////////////////////
  257. VOID
  258. LogErrorW(
  259. IN DWORD dwMessageId,
  260. IN DWORD cNumberOfSubStrings,
  261. IN LPWSTR *plpwsSubStrings,
  262. IN DWORD dwErrorCode
  263. );
  264. VOID
  265. LogEventW(
  266. IN DWORD wEventType,
  267. IN DWORD dwMessageId,
  268. IN DWORD cNumberOfSubStrings,
  269. IN LPWSTR *plpwsSubStrings
  270. );
  271. #ifdef UNICODE
  272. #define LogError LogErrorW
  273. #define LogEvent LogEventW
  274. #else
  275. #define LogError LogErrorA
  276. #define LogEvent LogEventA
  277. #endif
  278. //////////////////////////////////////////////////////////////////////////////
  279. // //
  280. // The following functions allow the caller to specify the event source. //
  281. // //
  282. // Call RouterLogRegister with the strings which would be passed to //
  283. // RegisterEventSource; this returns a handle which can be passed //
  284. // to the functions RouterLogEvent and RouterLogEventData. //
  285. // //
  286. // Call RouterLogDeregister to close the handle. //
  287. // //
  288. // Macros are provided for the different kinds of event log entrys: //
  289. // RouterLogError logs an error (EVENTLOG_ERROR_TYPE) //
  290. // RouterLogWarning logs a warning (EVENTLOG_WARNING_TYPE) //
  291. // RouterLogInformation logs information (EVENTLOG_INFORMATION_TYPE) //
  292. // //
  293. //////////////////////////////////////////////////////////////////////////////
  294. //////////////////////////////////////////////////////////////////////////////
  295. // //
  296. // ANSI prototypes //
  297. // //
  298. //////////////////////////////////////////////////////////////////////////////
  299. HANDLE
  300. RouterLogRegisterA(
  301. LPCSTR lpszSource
  302. );
  303. VOID
  304. RouterLogDeregisterA(
  305. HANDLE hLogHandle
  306. );
  307. VOID
  308. RouterLogEventA(
  309. IN HANDLE hLogHandle,
  310. IN DWORD dwEventType,
  311. IN DWORD dwMessageId,
  312. IN DWORD dwSubStringCount,
  313. IN LPSTR *plpszSubStringArray,
  314. IN DWORD dwErrorCode
  315. );
  316. VOID
  317. RouterLogEventDataA(
  318. IN HANDLE hLogHandle,
  319. IN DWORD dwEventType,
  320. IN DWORD dwMessageId,
  321. IN DWORD dwSubStringCount,
  322. IN LPSTR *plpszSubStringArray,
  323. IN DWORD dwDataBytes,
  324. IN LPBYTE lpDataBytes
  325. );
  326. VOID
  327. RouterLogEventStringA(
  328. IN HANDLE hLogHandle,
  329. IN DWORD dwEventType,
  330. IN DWORD dwMessageId,
  331. IN DWORD dwSubStringCount,
  332. IN LPSTR *plpszSubStringArray,
  333. IN DWORD dwErrorCode,
  334. IN DWORD dwErrorIndex
  335. );
  336. VOID
  337. __cdecl
  338. RouterLogEventExA(
  339. IN HANDLE hLogHandle,
  340. IN DWORD dwEventType,
  341. IN DWORD dwErrorCode,
  342. IN DWORD dwMessageId,
  343. IN LPCSTR ptszFormat,
  344. ...
  345. );
  346. VOID
  347. RouterLogEventValistExA(
  348. IN HANDLE hLogHandle,
  349. IN DWORD dwEventType,
  350. IN DWORD dwErrorCode,
  351. IN DWORD dwMessageId,
  352. IN LPCSTR ptszFormat,
  353. IN va_list arglist
  354. );
  355. DWORD
  356. RouterGetErrorStringA(
  357. IN DWORD dwErrorCode,
  358. OUT LPSTR * lplpszErrorString
  359. );
  360. #define RouterLogErrorA(h,msg,count,array,err) \
  361. RouterLogEventA(h,EVENTLOG_ERROR_TYPE,msg,count,array,err)
  362. #define RouterLogWarningA(h,msg,count,array,err) \
  363. RouterLogEventA(h,EVENTLOG_WARNING_TYPE,msg,count,array,err)
  364. #define RouterLogInformationA(h,msg,count,array,err) \
  365. RouterLogEventA(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err)
  366. #define RouterLogErrorDataA(h,msg,count,array,c,buf) \
  367. RouterLogEventDataA(h,EVENTLOG_ERROR_TYPE,msg,count,array,c,buf)
  368. #define RouterLogWarningDataA(h,msg,count,array,c,buf) \
  369. RouterLogEventDataA(h,EVENTLOG_WARNING_TYPE,msg,count,array,c,buf)
  370. #define RouterLogInformationDataA(h,msg,count,array,c,buf) \
  371. RouterLogEventDataA(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,c,buf)
  372. #define RouterLogErrorStringA(h,msg,count,array,err,index) \
  373. RouterLogEventStringA(h,EVENTLOG_ERROR_TYPE,msg,count,array, err,index)
  374. #define RouterLogWarningStringA(h,msg,count,array,err,index) \
  375. RouterLogEventStringA(h,EVENTLOG_WARNING_TYPE,msg,count,array,err,index)
  376. #define RouterLogInformationStringA(h,msg,count,array, err,index) \
  377. RouterLogEventStringA(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err,\
  378. index)
  379. //////////////////////////////////////////////////////////////////////////////
  380. // //
  381. // Unicode prototypes //
  382. // //
  383. //////////////////////////////////////////////////////////////////////////////
  384. HANDLE
  385. RouterLogRegisterW(
  386. LPCWSTR lpszSource
  387. );
  388. VOID
  389. RouterLogDeregisterW(
  390. HANDLE hLogHandle
  391. );
  392. VOID
  393. RouterLogEventW(
  394. IN HANDLE hLogHandle,
  395. IN DWORD dwEventType,
  396. IN DWORD dwMessageId,
  397. IN DWORD dwSubStringCount,
  398. IN LPWSTR *plpszSubStringArray,
  399. IN DWORD dwErrorCode
  400. );
  401. VOID
  402. RouterLogEventDataW(
  403. IN HANDLE hLogHandle,
  404. IN DWORD dwEventType,
  405. IN DWORD dwMessageId,
  406. IN DWORD dwSubStringCount,
  407. IN LPWSTR *plpszSubStringArray,
  408. IN DWORD dwDataBytes,
  409. IN LPBYTE lpDataBytes
  410. );
  411. VOID
  412. RouterLogEventStringW(
  413. IN HANDLE hLogHandle,
  414. IN DWORD dwEventType,
  415. IN DWORD dwMessageId,
  416. IN DWORD dwSubStringCount,
  417. IN LPWSTR *plpszSubStringArray,
  418. IN DWORD dwErrorCode,
  419. IN DWORD dwErrorIndex
  420. );
  421. VOID
  422. __cdecl
  423. RouterLogEventExW(
  424. IN HANDLE hLogHandle,
  425. IN DWORD dwEventType,
  426. IN DWORD dwErrorCode,
  427. IN DWORD dwMessageId,
  428. IN LPCWSTR ptszFormat,
  429. ...
  430. );
  431. VOID
  432. RouterLogEventValistExW(
  433. IN HANDLE hLogHandle,
  434. IN DWORD dwEventType,
  435. IN DWORD dwErrorCode,
  436. IN DWORD dwMessageId,
  437. IN LPCWSTR ptszFormat,
  438. IN va_list arglist
  439. );
  440. DWORD
  441. RouterGetErrorStringW(
  442. IN DWORD dwErrorCode,
  443. OUT LPWSTR * lplpwszErrorString
  444. );
  445. #define RouterLogErrorW(h,msg,count,array,err) \
  446. RouterLogEventW(h,EVENTLOG_ERROR_TYPE,msg,count,array,err)
  447. #define RouterLogWarningW(h,msg,count,array,err) \
  448. RouterLogEventW(h,EVENTLOG_WARNING_TYPE,msg,count,array,err)
  449. #define RouterLogInformationW(h,msg,count,array,err) \
  450. RouterLogEventW(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err)
  451. #define RouterLogErrorDataW(h,msg,count,array,c,buf) \
  452. RouterLogEventDataW(h,EVENTLOG_ERROR_TYPE,msg,count,array,c,buf)
  453. #define RouterLogWarningDataW(h,msg,count,array,c,buf) \
  454. RouterLogEventDataW(h,EVENTLOG_WARNING_TYPE,msg,count,array,c,buf)
  455. #define RouterLogInformationDataW(h,msg,count,array,c,buf) \
  456. RouterLogEventDataW(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,c,buf)
  457. #define RouterLogErrorStringW(h,msg,count,array,err,index) \
  458. RouterLogEventStringW(h,EVENTLOG_ERROR_TYPE,msg,count,array,err,index)
  459. #define RouterLogWarningStringW(h,msg,count,array,err,index) \
  460. RouterLogEventStringW(h,EVENTLOG_WARNING_TYPE,msg,count,array,err,index)
  461. #define RouterLogInformationStringW(h,msg,count,array,err,index) \
  462. RouterLogEventStringW(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err,\
  463. index)
  464. #ifdef UNICODE
  465. #define RouterLogRegister RouterLogRegisterW
  466. #define RouterLogDeregister RouterLogDeregisterW
  467. #define RouterLogEvent RouterLogEventW
  468. #define RouterLogError RouterLogErrorW
  469. #define RouterLogWarning RouterLogWarningW
  470. #define RouterLogInformation RouterLogInformationW
  471. #define RouterLogEventData RouterLogEventDataW
  472. #define RouterLogErrorData RouterLogErrorDataW
  473. #define RouterLogWarningData RouterLogWarningDataW
  474. #define RouterLogInformationData RouterLogInformationDataW
  475. #define RouterLogEventString RouterLogEventStringW
  476. #define RouterLogEventEx RouterLogEventExW
  477. #define RouterLogEventValistEx RouterLogEventValistExW
  478. #define RouterLogErrorString RouterLogErrorStringW
  479. #define RouterLogWarningString RouterLogWarningStringW
  480. #define RouterLogInformationString RouterLogInformationStringW
  481. #define RouterGetErrorString RouterGetErrorStringW
  482. #
  483. #else
  484. #define RouterLogRegister RouterLogRegisterA
  485. #define RouterLogDeregister RouterLogDeregisterA
  486. #define RouterLogEvent RouterLogEventA
  487. #define RouterLogError RouterLogErrorA
  488. #define RouterLogWarning RouterLogWarningA
  489. #define RouterLogInformation RouterLogInformationA
  490. #define RouterLogEventData RouterLogEventDataA
  491. #define RouterLogErrorData RouterLogErrorDataA
  492. #define RouterLogWarningData RouterLogWarningDataA
  493. #define RouterLogInformationData RouterLogInformationDataA
  494. #define RouterLogEventString RouterLogEventStringA
  495. #define RouterLogEventEx RouterLogEventExA
  496. #define RouterLogEventValistEx RouterLogEventValistExA
  497. #define RouterLogErrorString RouterLogErrorStringA
  498. #define RouterLogWarningString RouterLogWarningStringA
  499. #define RouterLogInformationString RouterLogInformationStringA
  500. #define RouterGetErrorString RouterGetErrorStringA
  501. #endif
  502. //////////////////////////////////////////////////////////////////////////////
  503. // //
  504. // WORKER THREAD POOL FUNCTIONS //
  505. // //
  506. //////////////////////////////////////////////////////////////////////////////
  507. //////////////////////////////////////////////////////////////////////////////
  508. // //
  509. // definition of worker function passed in QueueWorkItem API //
  510. // //
  511. //////////////////////////////////////////////////////////////////////////////
  512. typedef VOID (APIENTRY * WORKERFUNCTION)(PVOID);
  513. //////////////////////////////////////////////////////////////////////////////
  514. // //
  515. // Function: Queues the supplied work item in the work queue. //
  516. // //
  517. // functionptr: function to be called must be of WORKERFUNCTION type //
  518. // context: opaque ptr //
  519. // serviceinalertablethread: if TRUE gets scheduled in //
  520. // a alertably waiting thread that never dies //
  521. // Returns: 0 (success) //
  522. // Win32 error codes for cases like out of memory //
  523. // //
  524. //////////////////////////////////////////////////////////////////////////////
  525. DWORD
  526. APIENTRY
  527. QueueWorkItem(
  528. IN WORKERFUNCTION functionptr,
  529. IN PVOID context,
  530. IN BOOL serviceinalertablethread
  531. );
  532. //////////////////////////////////////////////////////////////////////////////
  533. // //
  534. // Function: Associates file handle with the completion port (all //
  535. // asynchronous i/o on this handle will be queued to //
  536. // the completion port) //
  537. // //
  538. // FileHandle: File handle to be associated with completion port //
  539. // //
  540. // CompletionProc: Procedure to be called when io associated with the file //
  541. // handle completes. This function will be executed in //
  542. // the context of non-alertable worker thread //
  543. // //
  544. //////////////////////////////////////////////////////////////////////////////
  545. DWORD
  546. APIENTRY
  547. SetIoCompletionProc (
  548. IN HANDLE FileHandle,
  549. IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionProc
  550. );
  551. //////////////////////////////////////////////////////////////////////////////
  552. // //
  553. // The following defines are included here as a hint on how the worker //
  554. // thread pool is managed: //
  555. // //
  556. // There are NUM_ALERTABLE_THREADS permanent threads that never quit and //
  557. // wait alertably on a alertable worker queue. These threads should solely //
  558. // be used for work items that intiate asyncronous operation (file io, //
  559. // waitable timer) that ABSOLUTELY require APCs to complete (preferable //
  560. // method for IO is the usage of completio port API) //
  561. // //
  562. // There is a pool of the threads that wait on completion port //
  563. // that used both for processing of IO and non-IO related work items //
  564. // //
  565. // The minimum number of threads is Number of processors //
  566. // The maximum number of threads is MAX_WORKER_THREADS //
  567. // //
  568. // A new thread is created if worker queue has not been served for more //
  569. // that WORK_QUEUE_TIMEOUT //
  570. // The existing thread will be shut down if it is not used for more than //
  571. // THREAD_IDLE_TIMEOUT //
  572. // //
  573. // Note that worker threads age guaranteed to be alive for at least //
  574. // THREAD_IDLE_TIMEOUT after the last work item is executed. This timeout //
  575. // is chosen such that bulk of IO request could be completed before it //
  576. // expires. If it is not enough for your case, use alertable thread with //
  577. // APC, or create your own thread. //
  578. // //
  579. // Note: changing these flags will not change anything. //
  580. // //
  581. //////////////////////////////////////////////////////////////////////////////
  582. //////////////////////////////////////////////////////////////////////////////
  583. // //
  584. // Number of alertable threads //
  585. // //
  586. //////////////////////////////////////////////////////////////////////////////
  587. #define NUM_ALERTABLE_THREADS 2
  588. //////////////////////////////////////////////////////////////////////////////
  589. // //
  590. // Max number of threads at any time //
  591. // //
  592. //////////////////////////////////////////////////////////////////////////////
  593. #define MAX_WORKER_THREADS 10
  594. //////////////////////////////////////////////////////////////////////////////
  595. // //
  596. // Time that the worker queue is not served before starting new thread //
  597. // //
  598. //////////////////////////////////////////////////////////////////////////////
  599. #define WORK_QUEUE_TIMEOUT 1 //sec
  600. //////////////////////////////////////////////////////////////////////////////
  601. // //
  602. // Time that thread has to be idle before exiting //
  603. // //
  604. //////////////////////////////////////////////////////////////////////////////
  605. #define THREAD_IDLE_TIMEOUT 10 //sec
  606. //////////////////////////////////////////////////////////////////////////////
  607. // //
  608. // ROUTER ASSERT DECLARATION //
  609. // //
  610. //////////////////////////////////////////////////////////////////////////////
  611. VOID
  612. RouterAssert(
  613. IN PSTR pszFailedAssertion,
  614. IN PSTR pszFileName,
  615. IN DWORD dwLineNumber,
  616. IN PSTR pszMessage OPTIONAL
  617. );
  618. #if DBG
  619. #define RTASSERT(exp) \
  620. if (!(exp)) \
  621. RouterAssert(#exp, __FILE__, __LINE__, NULL)
  622. #define RTASSERTMSG(msg, exp) \
  623. if (!(exp)) \
  624. RouterAssert(#exp, __FILE__, __LINE__, msg)
  625. #else
  626. #define RTASSERT(exp)
  627. #define RTASSERTMSG(msg, exp)
  628. #endif
  629. //////////////////////////////////////////////////////////////////////////////
  630. // //
  631. // REGISTRY CONFIGURATION FUNCTIONS //
  632. // //
  633. // The following definitions are used to read configuration information //
  634. // about installed protocols. //
  635. // //
  636. // Call 'MprSetupProtocolEnum' to enumerate the routing-protocols //
  637. // for transport 'dwTransportId'. This fills an array with entries //
  638. // of type 'MPR_PROTOCOL_0'. //
  639. // //
  640. // The array loaded can be destroyed by calling 'MprSetupProtocolFree'. //
  641. // //
  642. //////////////////////////////////////////////////////////////////////////////
  643. #define RTUTILS_MAX_PROTOCOL_NAME_LEN 40
  644. #define RTUTILS_MAX_PROTOCOL_DLL_LEN 48
  645. //
  646. // the below two names should not be used
  647. //
  648. #ifndef MAX_PROTOCOL_NAME_LEN
  649. #define MAX_PROTOCOL_NAME_LEN RTUTILS_MAX_PROTOCOL_NAME_LEN
  650. #else
  651. #undef MAX_PROTOCOL_NAME_LEN
  652. #endif
  653. #define MAX_PROTOCOL_DLL_LEN RTUTILS_MAX_PROTOCOL_DLL_LEN
  654. typedef struct _MPR_PROTOCOL_0 {
  655. DWORD dwProtocolId; // e.g. IP_RIP
  656. WCHAR wszProtocol[RTUTILS_MAX_PROTOCOL_NAME_LEN+1]; // e.g. "IPRIP"
  657. WCHAR wszDLLName[RTUTILS_MAX_PROTOCOL_DLL_LEN+1]; // e.g. "iprip2.dll"
  658. } MPR_PROTOCOL_0;
  659. DWORD APIENTRY
  660. MprSetupProtocolEnum(
  661. IN DWORD dwTransportId,
  662. OUT LPBYTE* lplpBuffer, // MPR_PROTOCOL_0
  663. OUT LPDWORD lpdwEntriesRead
  664. );
  665. DWORD APIENTRY
  666. MprSetupProtocolFree(
  667. IN LPVOID lpBuffer
  668. );
  669. //////////////////////////////////////////////////////////////////////////////
  670. // Extensions to Rtutils to improve worker thread utilization. //
  671. // //
  672. //////////////////////////////////////////////////////////////////////////////
  673. #define ROUTING_RESERVED
  674. #define OPT1_1
  675. #define OPT1_2
  676. #define OPT2_1
  677. #define OPT2_2
  678. #define OPT3_1
  679. #define OPT3_2
  680. //
  681. // When everyone is migrated to using Winsock2
  682. //
  683. #if 0
  684. //==========================================================================================================//
  685. //==========================================================================================================//
  686. // ASYNC_SOCKET_DATA structure is used to pass / receive back data from an //
  687. // asynchronous wait recv from call //
  688. typedef struct _ASYNC_SOCKET_DATA {
  689. OVERLAPPED Overlapped; // reserved. not to be used
  690. IN WSABUF WsaBuf; // WsaBuf.buf to be initialized to point to buffer
  691. // WsaBuf.len set to the length of the buffer
  692. OUT SOCKADDR_IN SrcAddress; // AsyncWsaRecvFrom fills this with the source address of the packet
  693. OUT DWORD NumBytesReceived; // AsyncWsaRecvFrom fills this with the number of bytes returned in the packet
  694. IN OUT DWORD Flags; // Used to set flags for WSARecvFrom, and returns the flags set by WSARecvFrom
  695. OUT DWORD Status; // status returned by IO Completion Port
  696. IN WORKERFUNCTION pFunction; // Function to be executed on receiving packet
  697. IN PVOID pContext; // context for the above function
  698. } ASYNC_SOCKET_DATA, *PASYNC_SOCKET_DATA;
  699. // AsyncSocketInit() binds the socket to the IOCompletionPort. This should be called//
  700. // after the socket is created and before AsyncWsaRecvFrom() call is made //
  701. DWORD
  702. APIENTRY
  703. AsyncSocketInit (
  704. SOCKET sock
  705. );
  706. // This should be called only after the appropriate fields in SockData are initialized //
  707. // This sets up an asynchronous WSARecvFrom(), and on its return dispatches the //
  708. // function to a worker thread. It should be remembered that the function will run in //
  709. // a worker thread which might later on be deleted. So SetWaitableTimer() and //
  710. // asynchronous receive calls should be avoided unless you are sure that it would not be//
  711. // a problem. It is adviced that if you want the function to run in an alertable thread,//
  712. // then have the callback function queue a work item to alertable thread. Queue work //
  713. // items to alertable worker threads for SetWaitableTimer() and async receives. //
  714. // One must not make many AsyncWSArecvFrom() calls, as the buffer are non-paged //
  715. DWORD
  716. APIENTRY
  717. AsyncWSARecvFrom (
  718. SOCKET sock,
  719. PASYNC_SOCKET_DATA pSockData
  720. );
  721. #endif // all winsock2 functions
  722. //==========================================================================================================//
  723. //==========================================================================================================//
  724. // forward declarations
  725. struct _WAIT_THREAD_ENTRY;
  726. struct _WT_EVENT_ENTRY;
  727. typedef struct _WT_TIMER_ENTRY {
  728. LONGLONG te_Timeout;
  729. WORKERFUNCTION te_Function;
  730. PVOID te_Context;
  731. DWORD te_ContextSz;
  732. BOOL te_RunInServer;
  733. DWORD te_Status;
  734. #define TIMER_INACTIVE 3
  735. #define TIMER_ACTIVE 4
  736. DWORD te_ServerId;
  737. struct _WAIT_THREAD_ENTRY *teP_wte;
  738. LIST_ENTRY te_ServerLinks;
  739. LIST_ENTRY te_Links;
  740. BOOL te_Flag; //todo: not used
  741. DWORD te_TimerId;
  742. } WT_TIMER_ENTRY, *PWT_TIMER_ENTRY;
  743. typedef struct _WT_WORK_ITEM {
  744. WORKERFUNCTION wi_Function; // function to call
  745. PVOID wi_Context; // context passed into function call
  746. DWORD wi_ContextSz; // size of context, used for allocating
  747. BOOL wi_RunInServer; // run in wait server thread or get queued to some worker thread
  748. struct _WT_EVENT_ENTRY *wiP_ee;
  749. LIST_ENTRY wi_ServerLinks;
  750. LIST_ENTRY wi_Links; //todo not req // link to next and prev element
  751. } WT_WORK_ITEM, *PWT_WORK_ITEM;
  752. #define WT_EVENT_BINDING WT_WORK_ITEM
  753. #define PWT_EVENT_BINDING PWT_WORK_ITEM
  754. //
  755. // WT_EVENT_ENTRY
  756. //
  757. typedef struct _WT_EVENT_ENTRY {
  758. HANDLE ee_Event;
  759. BOOL ee_bManualReset; // is the event manually reset
  760. BOOL ee_bInitialState; // is the initial state of the event active
  761. BOOL ee_bDeleteEvent; // was the event created as part of createWaitEvent
  762. DWORD ee_Status; // current status of the event entry
  763. BOOL ee_bHighPriority;
  764. LIST_ENTRY eeL_wi;
  765. BOOL ee_bSignalSingle; // signal single function or multiple functions // how many functions to activate when event signalled (default:1)
  766. BOOL ee_bOwnerSelf; // the owner if the client which create this event
  767. INT ee_ArrayIndex; // index in the events array if active
  768. DWORD ee_ServerId; // Id of server: used while deleting
  769. struct _WAIT_THREAD_ENTRY *eeP_wte; // pointer to wait thread entry
  770. LIST_ENTRY ee_ServerLinks; // used by wait server thread
  771. LIST_ENTRY ee_Links; // used by client
  772. DWORD ee_RefCount;
  773. BOOL ee_bFlag; //todo: notused // reserved for use during deletion
  774. DWORD ee_EventId; //todo: remove it, being used only for testing/debugging
  775. } WT_EVENT_ENTRY, *PWT_EVENT_ENTRY;
  776. // PROTOTYPES OF FUNCTIONS USED IN THIS FILE ONLY
  777. //
  778. // used by client to create a wait event
  779. // context size should be 0 if you are passing a dword instead of a pointer
  780. // if pEvent field is set, then lpName and security attributes are ignored
  781. // if pFunction is NULL, then pContext, dwContextSz, and bRunInServerContext are ignored
  782. PWT_EVENT_ENTRY
  783. APIENTRY
  784. CreateWaitEvent (
  785. //IN PWT_EVENT_ENTRY pEventEntry, // handle to event entry if initialized by others
  786. IN HANDLE pEvent OPT1_1, // handle to event if already created
  787. IN LPSECURITY_ATTRIBUTES lpEventAttributes OPT1_2, // pointer to security attributes
  788. IN BOOL bManualReset,
  789. IN BOOL bInitialState,
  790. IN LPCTSTR lpName OPT1_2, // pointer to event-object name
  791. IN BOOL bHighPriority, // create high priority event
  792. IN WORKERFUNCTION pFunction OPT2_1, // if null, means will be set by other clients
  793. IN PVOID pContext OPT2_1, // can be null
  794. IN DWORD dwContextSz OPT2_1, // size of context: used for allocating context to functions
  795. IN BOOL bRunInServerContext OPT2_1 // run in server thread or get dispatched to worker thread
  796. );
  797. //dwContextSz should be 0 if a dword is being passed. >0 only if pointer to block of that size is being passed.
  798. PWT_EVENT_BINDING
  799. APIENTRY
  800. CreateWaitEventBinding (
  801. IN PWT_EVENT_ENTRY pee,
  802. IN WORKERFUNCTION pFunction,
  803. IN PVOID pContext,
  804. IN DWORD dwContextSz,
  805. IN BOOL bRunInServerContext
  806. );
  807. PWT_TIMER_ENTRY
  808. APIENTRY
  809. CreateWaitTimer (
  810. IN WORKERFUNCTION pFunction,
  811. IN PVOID pContext,
  812. IN DWORD dwContextSz,
  813. IN BOOL bRunInServerContext
  814. );
  815. DWORD
  816. APIENTRY
  817. DeRegisterWaitEventBindingSelf (
  818. IN PWT_EVENT_BINDING pwiWorkItem
  819. );
  820. DWORD
  821. APIENTRY
  822. DeRegisterWaitEventBinding (
  823. IN PWT_EVENT_BINDING pwiWorkItem
  824. );
  825. //all the events and timers should be registered with one waitThread server
  826. //todo: change the above requirement
  827. DWORD
  828. APIENTRY
  829. DeRegisterWaitEventsTimers (
  830. PLIST_ENTRY pLEvents, // list of events linked by ee_Links field
  831. PLIST_ENTRY pLTimers // list of timers linked by te_Links field:
  832. //these lists can be a single list entry, or a multiple entry list with a list header entry.
  833. );
  834. // this should be used only when called within a server thread
  835. DWORD
  836. APIENTRY
  837. DeRegisterWaitEventsTimersSelf (
  838. IN PLIST_ENTRY pLEvents,
  839. IN PLIST_ENTRY pLTimers
  840. );
  841. DWORD
  842. APIENTRY
  843. RegisterWaitEventBinding (
  844. IN PWT_EVENT_BINDING pwiWorkItem
  845. );
  846. // Register the client with the wait thread
  847. DWORD
  848. APIENTRY
  849. RegisterWaitEventsTimers (
  850. IN PLIST_ENTRY pLEventsToAdd,
  851. IN PLIST_ENTRY pLTimersToAdd
  852. );
  853. DWORD
  854. APIENTRY
  855. UpdateWaitTimer (
  856. IN PWT_TIMER_ENTRY pte,
  857. IN LONGLONG *time
  858. );
  859. VOID
  860. APIENTRY
  861. WTFree (
  862. PVOID ptr
  863. );
  864. //used to free wait-event. Should be deallocated using DeRegisterWaitEventsTimers
  865. //This function is to be used only when the events have not been registered
  866. VOID
  867. APIENTRY
  868. WTFreeEvent (
  869. IN PWT_EVENT_ENTRY peeEvent
  870. );
  871. //used to free wait-timer. Should be deallocated using DeRegisterWaitEventsTimers
  872. //This function is to be used only when the timers have not been registered
  873. VOID
  874. APIENTRY
  875. WTFreeTimer (
  876. IN PWT_TIMER_ENTRY pteTimer
  877. );
  878. VOID
  879. APIENTRY
  880. DebugPrintWaitWorkerThreads (
  881. DWORD dwDebugLevel
  882. );
  883. #define DEBUGPRINT_FILTER_NONCLIENT_EVENTS 0x2
  884. #define DEBUGPRINT_FILTER_EVENTS 0x4
  885. #define DEBUGPRINT_FILTER_TIMERS 0x8
  886. //
  887. //ERROR VALUES
  888. //
  889. #define ERROR_WAIT_THREAD_UNAVAILABLE 1
  890. #define ERROR_WT_EVENT_ALREADY_DELETED 2
  891. #define TIMER_HIGH(time) \
  892. (((LARGE_INTEGER*)&time)->HighPart)
  893. #define TIMER_LOW(time) \
  894. (((LARGE_INTEGER*)&time)->LowPart)
  895. #ifdef __cplusplus
  896. }
  897. #endif
  898. #endif // ___ROUTING_RTUTILS_H__