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.

2023 lines
49 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. APISTUB.C
  5. Abstract:
  6. This module contains the client ends of the Elf APIs.
  7. Author:
  8. Rajen Shah (rajens) 29-Jul-1991
  9. Revision History:
  10. 29-Jul-1991 RajenS
  11. Created
  12. 13-Jan-1997 Added extensions for clustering to support replicated
  13. eventlogs
  14. --*/
  15. /****
  16. @doc EXTERNAL INTERFACES EVTLOG
  17. ****/
  18. #include <elfclntp.h>
  19. #include <lmerr.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. //
  23. // Global data
  24. //
  25. PUNICODE_STRING pGlobalComputerNameU;
  26. PANSI_STRING pGlobalComputerNameA;
  27. long glInitNameCount = 0;
  28. VOID
  29. w_GetComputerName ( )
  30. /*++
  31. Routine Description:
  32. This routine gets the name of the computer. It checks the global
  33. variable to see if the computer name has already been determined.
  34. If not, it updates that variable with the name.
  35. It does this for the UNICODE and the ANSI versions.
  36. Arguments:
  37. NONE
  38. Return Value:
  39. NONE
  40. --*/
  41. {
  42. PUNICODE_STRING pNameU;
  43. PANSI_STRING pNameA;
  44. LPSTR szName;
  45. LPWSTR wszName;
  46. DWORD dwStatus;
  47. long lTemp;
  48. // Grab the lock.
  49. lTemp = InterlockedExchange(&glInitNameCount, 1);
  50. if(lTemp != 0)
  51. {
  52. // someone else got the lock, spin till they are done and then return.
  53. while(lTemp == 1)
  54. {
  55. Sleep(100);
  56. lTemp = InterlockedExchange(&glInitNameCount, 1);
  57. }
  58. if(pGlobalComputerNameU)
  59. {
  60. glInitNameCount = 0;
  61. return;
  62. }
  63. }
  64. //
  65. // now that we own the lock, do one last check to make sure someone else didnt do the allocation
  66. //
  67. if(pGlobalComputerNameU)
  68. {
  69. glInitNameCount = 0;
  70. return;
  71. }
  72. pNameU = MIDL_user_allocate (sizeof (UNICODE_STRING));
  73. pNameA = MIDL_user_allocate (sizeof (ANSI_STRING));
  74. if ((pNameU != NULL) && (pNameA != NULL)) {
  75. dwStatus = ElfpGetComputerName(&szName, &wszName);
  76. if (dwStatus == NO_ERROR) {
  77. //
  78. // ElfpComputerName has allocated a buffer to contain the
  79. // ASCII name of the computer. We use that for the ANSI
  80. // string structure.
  81. //
  82. RtlInitAnsiString ( pNameA, szName );
  83. RtlInitUnicodeString ( pNameU, wszName );
  84. } else {
  85. //
  86. // We could not get the computer name for some reason. Set up
  87. // the golbal pointer to point to the NULL string.
  88. //
  89. RtlInitAnsiString ( pNameA, "\0");
  90. RtlInitUnicodeString ( pNameU, L"\0");
  91. }
  92. pGlobalComputerNameU = pNameU;
  93. pGlobalComputerNameA = pNameA;
  94. }
  95. else {
  96. //
  97. // In case one of the two was allocated.
  98. //
  99. MIDL_user_free (pNameU);
  100. MIDL_user_free (pNameA);
  101. }
  102. glInitNameCount = 0;
  103. }
  104. PUNICODE_STRING
  105. TmpGetComputerNameW ( )
  106. /*++
  107. Routine Description:
  108. This routine gets the UNICODE name of the computer. It checks the global
  109. variable to see if the computer name has already been determined.
  110. If not, it calls the worker routine to do that.
  111. Arguments:
  112. NONE
  113. Return Value:
  114. Returns a pointer to the computer name, or a NULL.
  115. --*/
  116. {
  117. if (pGlobalComputerNameU == NULL) {
  118. w_GetComputerName();
  119. }
  120. return (pGlobalComputerNameU);
  121. }
  122. PANSI_STRING
  123. TmpGetComputerNameA ( )
  124. /*++
  125. Routine Description:
  126. This routine gets the ANSI name of the computer. It checks the global
  127. variable to see if the computer name has already been determined.
  128. If not, it calls the worker routine to do that.
  129. Arguments:
  130. NONE
  131. Return Value:
  132. Returns a pointer to the computer name, or a NULL.
  133. --*/
  134. {
  135. if (pGlobalComputerNameA == NULL) {
  136. w_GetComputerName();
  137. }
  138. return (pGlobalComputerNameA);
  139. }
  140. //
  141. // These APIs only have one interface, since they don't take or return strings
  142. //
  143. NTSTATUS
  144. ElfNumberOfRecords(
  145. IN HANDLE LogHandle,
  146. OUT PULONG NumberOfRecords
  147. )
  148. {
  149. NTSTATUS status;
  150. //
  151. // Make sure the output pointer is valid
  152. //
  153. if (!NumberOfRecords) {
  154. return(STATUS_INVALID_PARAMETER);
  155. }
  156. //
  157. // Do the RPC call with an exception handler since RPC will raise an
  158. // exception if anything fails. It is up to us to figure out what
  159. // to do once the exception is raised.
  160. //
  161. RpcTryExcept {
  162. // Call service entry point
  163. status = ElfrNumberOfRecords (
  164. (IELF_HANDLE) LogHandle,
  165. NumberOfRecords
  166. );
  167. }
  168. RpcExcept (1) {
  169. status = I_RpcMapWin32Status(RpcExceptionCode());
  170. }
  171. RpcEndExcept
  172. return (status);
  173. }
  174. NTSTATUS
  175. ElfOldestRecord(
  176. IN HANDLE LogHandle,
  177. OUT PULONG OldestRecordNumber
  178. )
  179. {
  180. NTSTATUS status;
  181. //
  182. //
  183. // Make sure the output pointer is valid
  184. //
  185. if (!OldestRecordNumber) {
  186. return(STATUS_INVALID_PARAMETER);
  187. }
  188. // Do the RPC call with an exception handler since RPC will raise an
  189. // exception if anything fails. It is up to us to figure out what
  190. // to do once the exception is raised.
  191. //
  192. RpcTryExcept {
  193. // Call service entry point
  194. status = ElfrOldestRecord (
  195. (IELF_HANDLE) LogHandle,
  196. OldestRecordNumber
  197. );
  198. }
  199. RpcExcept (1) {
  200. status = I_RpcMapWin32Status(RpcExceptionCode());
  201. }
  202. RpcEndExcept
  203. return (status);
  204. }
  205. NTSTATUS
  206. ElfChangeNotify(
  207. IN HANDLE LogHandle,
  208. IN HANDLE Event
  209. )
  210. {
  211. NTSTATUS status;
  212. RPC_CLIENT_ID RpcClientId;
  213. CLIENT_ID ClientId;
  214. //
  215. // Map the handles to something that RPC can understand
  216. //
  217. ClientId = NtCurrentTeb()->ClientId;
  218. RpcClientId.UniqueProcess = (ULONG)((ULONG_PTR)ClientId.UniqueProcess);
  219. RpcClientId.UniqueThread = (ULONG)((ULONG_PTR)ClientId.UniqueThread);
  220. //
  221. // Do the RPC call with an exception handler since RPC will raise an
  222. // exception if anything fails. It is up to us to figure out what
  223. // to do once the exception is raised.
  224. //
  225. RpcTryExcept {
  226. // Call service entry point
  227. status = ElfrChangeNotify (
  228. (IELF_HANDLE)((ULONG_PTR)LogHandle),
  229. RpcClientId,
  230. (DWORD)(ULONG_PTR)Event
  231. );
  232. }
  233. RpcExcept (1) {
  234. status = I_RpcMapWin32Status(RpcExceptionCode());
  235. }
  236. RpcEndExcept
  237. return (status);
  238. }
  239. NTSTATUS
  240. ElfGetLogInformation(
  241. IN HANDLE LogHandle,
  242. IN ULONG InfoLevel,
  243. OUT PVOID lpBuffer,
  244. IN ULONG cbBufSize,
  245. OUT PULONG pcbBytesNeeded
  246. )
  247. {
  248. NTSTATUS ntStatus;
  249. //
  250. // Make sure the Infolevel is valid
  251. //
  252. switch (InfoLevel) {
  253. case EVENTLOG_FULL_INFO:
  254. RpcTryExcept {
  255. // Call service entry point
  256. ntStatus = ElfrGetLogInformation(
  257. (IELF_HANDLE) LogHandle,
  258. InfoLevel,
  259. lpBuffer,
  260. cbBufSize,
  261. pcbBytesNeeded);
  262. }
  263. RpcExcept (1) {
  264. ntStatus = I_RpcMapWin32Status(RpcExceptionCode());
  265. }
  266. RpcEndExcept
  267. break;
  268. default:
  269. ntStatus = STATUS_INVALID_LEVEL;
  270. break;
  271. }
  272. return ntStatus;
  273. }
  274. //
  275. // UNICODE APIs
  276. //
  277. NTSTATUS
  278. ElfOpenEventLogW (
  279. IN PUNICODE_STRING UNCServerName,
  280. IN PUNICODE_STRING LogName,
  281. OUT PHANDLE LogHandle
  282. )
  283. /*++
  284. Routine Description:
  285. This is the client DLL entry point for the ElfOpenEventLog API.
  286. It creates an RPC binding for the server specified, and stores that
  287. and additional data away. It returns a handle to the caller that can
  288. be used to later on access the handle-specific information.
  289. Arguments:
  290. UNCServerName - Server with which to bind for subsequent operations.
  291. LogName - Supplies the name of the module for the logfile
  292. to associate with this handle.
  293. LogHandle - Location where log handle is to be returned.
  294. Return Value:
  295. Returns an NTSTATUS code and, if no error, a handle that can be used
  296. for subsequent Elf API calls.
  297. --*/
  298. {
  299. NTSTATUS status = STATUS_SUCCESS;
  300. NTSTATUS ApiStatus;
  301. UNICODE_STRING RegModuleName;
  302. EVENTLOG_HANDLE_W ServerNameString;
  303. BOOLEAN fWasEnabled = FALSE;
  304. BOOL fIsSecurityLog;
  305. //
  306. // Make sure input & output pointers are valid
  307. //
  308. if (!LogHandle || !LogName || LogName->Length == 0) {
  309. return(STATUS_INVALID_PARAMETER);
  310. }
  311. if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) {
  312. ServerNameString = UNCServerName->Buffer;
  313. } else {
  314. ServerNameString = NULL;
  315. }
  316. RtlInitUnicodeString( &RegModuleName, UNICODE_NULL);
  317. // Call service via RPC. Pass in major and minor version numbers.
  318. *LogHandle = NULL; // Must be NULL so RPC fills it in
  319. fIsSecurityLog = (_wcsicmp(ELF_SECURITY_MODULE_NAME, LogName->Buffer) == 0);
  320. if (fIsSecurityLog) {
  321. //
  322. // Tacitly attempt to enable the SE_SECURITY_PRIVILEGE so we can
  323. // can check it on the server side. We ignore the return value
  324. // because it's possible for this call to fail here but for the
  325. // user to have this privilege if the log is on a remote server.
  326. //
  327. // Note that we make this call on behalf of the client to avoid
  328. // a regression when we check for the privilege on the server
  329. // side -- without this call, 3rd party apps that successfully
  330. // called this API before would fail. Under normal circumstances,
  331. // this is not an encouraged practice.
  332. //
  333. //
  334. // -- This should really be done via ImpersonateSelf()
  335. // and adjusting the thread token
  336. //
  337. ApiStatus = RtlAdjustPrivilege(SE_SECURITY_PRIVILEGE,
  338. TRUE,
  339. FALSE,
  340. &fWasEnabled);
  341. }
  342. //
  343. // Do the RPC call with an exception handler since RPC will raise an
  344. // exception if anything fails. It is up to us to figure out what
  345. // to do once the exception is raised.
  346. //
  347. RpcTryExcept {
  348. status = ElfrOpenELW(
  349. ServerNameString,
  350. (PRPC_UNICODE_STRING) LogName,
  351. (PRPC_UNICODE_STRING) &RegModuleName,
  352. ELF_VERSION_MAJOR,
  353. ELF_VERSION_MINOR,
  354. (PIELF_HANDLE) LogHandle
  355. );
  356. }
  357. RpcExcept (1) {
  358. status = I_RpcMapWin32Status(RpcExceptionCode());
  359. }
  360. RpcEndExcept
  361. if (fIsSecurityLog && NT_SUCCESS(ApiStatus)) {
  362. //
  363. // Restore the state
  364. //
  365. RtlAdjustPrivilege(SE_SECURITY_PRIVILEGE,
  366. fWasEnabled,
  367. FALSE,
  368. &fWasEnabled);
  369. }
  370. return (status);
  371. }
  372. NTSTATUS
  373. ElfRegisterEventSourceW (
  374. IN PUNICODE_STRING UNCServerName,
  375. IN PUNICODE_STRING ModuleName,
  376. OUT PHANDLE LogHandle
  377. )
  378. /*++
  379. Routine Description:
  380. This is the client DLL entry point for the ElfRegisterEventSource API.
  381. It creates an RPC binding for the server specified, and stores that
  382. and additional data away. It returns a handle to the caller that can
  383. be used to later on access the handle-specific information.
  384. Arguments:
  385. UNCServerName - Server with which to bind for subsequent operations.
  386. ModuleName - Supplies the name of the module to associate with
  387. this handle.
  388. LogHandle - Location where log handle is to be returned.
  389. Return Value:
  390. Returns an NTSTATUS code and, if no error, a handle that can be used
  391. for subsequent Elf API calls.
  392. --*/
  393. {
  394. NTSTATUS status = STATUS_SUCCESS;
  395. UNICODE_STRING RegModuleName;
  396. EVENTLOG_HANDLE_W ServerNameString;
  397. //
  398. // Make sure input & output pointers are valid
  399. //
  400. if (!LogHandle || !ModuleName || ModuleName->Length == 0) {
  401. return(STATUS_INVALID_PARAMETER);
  402. }
  403. if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) {
  404. ServerNameString = UNCServerName->Buffer;
  405. } else {
  406. ServerNameString = NULL;
  407. }
  408. RtlInitUnicodeString( &RegModuleName, UNICODE_NULL);
  409. // Call service via RPC. Pass in major and minor version numbers.
  410. *LogHandle = NULL; // Must be NULL so RPC fills it in
  411. //
  412. // Do the RPC call with an exception handler since RPC will raise an
  413. // exception if anything fails. It is up to us to figure out what
  414. // to do once the exception is raised.
  415. //
  416. RpcTryExcept {
  417. status = ElfrRegisterEventSourceW(
  418. ServerNameString,
  419. (PRPC_UNICODE_STRING)ModuleName,
  420. (PRPC_UNICODE_STRING)&RegModuleName,
  421. ELF_VERSION_MAJOR,
  422. ELF_VERSION_MINOR,
  423. (PIELF_HANDLE) LogHandle
  424. );
  425. }
  426. RpcExcept (1) {
  427. status = I_RpcMapWin32Status(RpcExceptionCode());
  428. }
  429. RpcEndExcept
  430. return (status);
  431. }
  432. NTSTATUS
  433. ElfOpenBackupEventLogW (
  434. IN PUNICODE_STRING UNCServerName,
  435. IN PUNICODE_STRING BackupFileName,
  436. OUT PHANDLE LogHandle
  437. )
  438. /*++
  439. Routine Description:
  440. This is the client DLL entry point for the ElfOpenBackupEventLog API.
  441. It creates an RPC binding for the server specified, and stores that
  442. and additional data away. It returns a handle to the caller that can
  443. be used to later on access the handle-specific information.
  444. Arguments:
  445. UNCServerName - Server with which to bind for subsequent operations.
  446. BackupFileName - Supplies the filename of the module to associate with
  447. this handle.
  448. LogHandle - Location where log handle is to be returned.
  449. Return Value:
  450. Returns an NTSTATUS code and, if no error, a handle that can be used
  451. for subsequent Elf API calls.
  452. --*/
  453. {
  454. NTSTATUS status = STATUS_SUCCESS;
  455. EVENTLOG_HANDLE_W ServerNameString;
  456. //
  457. // Make sure input & output pointers are valid
  458. //
  459. if (!LogHandle || !BackupFileName || BackupFileName->Length == 0) {
  460. return(STATUS_INVALID_PARAMETER);
  461. }
  462. if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) {
  463. ServerNameString = UNCServerName->Buffer;
  464. } else {
  465. ServerNameString = NULL;
  466. }
  467. // Call service via RPC. Pass in major and minor version numbers.
  468. *LogHandle = NULL; // Must be NULL so RPC fills it in
  469. //
  470. // Do the RPC call with an exception handler since RPC will raise an
  471. // exception if anything fails. It is up to us to figure out what
  472. // to do once the exception is raised.
  473. //
  474. RpcTryExcept {
  475. status = ElfrOpenBELW(
  476. ServerNameString,
  477. (PRPC_UNICODE_STRING)BackupFileName,
  478. ELF_VERSION_MAJOR,
  479. ELF_VERSION_MINOR,
  480. (PIELF_HANDLE) LogHandle
  481. );
  482. }
  483. RpcExcept (1) {
  484. status = I_RpcMapWin32Status(RpcExceptionCode());
  485. }
  486. RpcEndExcept
  487. return (status);
  488. }
  489. NTSTATUS
  490. ElfClearEventLogFileW (
  491. IN HANDLE LogHandle,
  492. IN PUNICODE_STRING BackupFileName
  493. )
  494. /*++
  495. Routine Description:
  496. This is the client DLL entry point for the ElfClearEventLogFile API.
  497. The call is passed to the eventlog service on the appropriate server
  498. identified by LogHandle.
  499. Arguments:
  500. LogHandle - Handle returned from a previous "Open" call. This is
  501. used to identify the module and the server.
  502. BackupFileName - Name of the file to back up the current log file.
  503. NULL implies not to back up the file.
  504. Return Value:
  505. Returns an NTSTATUS code.
  506. --*/
  507. {
  508. NTSTATUS status;
  509. //
  510. // Do the RPC call with an exception handler since RPC will raise an
  511. // exception if anything fails. It is up to us to figure out what
  512. // to do once the exception is raised.
  513. //
  514. RpcTryExcept {
  515. // Call service entry point
  516. status = ElfrClearELFW (
  517. (IELF_HANDLE) LogHandle,
  518. (PRPC_UNICODE_STRING)BackupFileName
  519. );
  520. }
  521. RpcExcept (1) {
  522. status = I_RpcMapWin32Status(RpcExceptionCode());
  523. }
  524. RpcEndExcept
  525. return (status);
  526. }
  527. NTSTATUS
  528. ElfBackupEventLogFileW (
  529. IN HANDLE LogHandle,
  530. IN PUNICODE_STRING BackupFileName
  531. )
  532. /*++
  533. Routine Description:
  534. This is the client DLL entry point for the ElfBackupEventLogFile API.
  535. The call is passed to the eventlog service on the appropriate server
  536. identified by LogHandle.
  537. Arguments:
  538. LogHandle - Handle returned from a previous "Open" call. This is
  539. used to identify the module and the server.
  540. BackupFileName - Name of the file to back up the current log file.
  541. Return Value:
  542. Returns an NTSTATUS code.
  543. --*/
  544. {
  545. NTSTATUS status;
  546. NTSTATUS ApiStatus;
  547. BOOLEAN fWasEnabled;
  548. //
  549. // Make sure input pointers are valid
  550. //
  551. if (!BackupFileName || BackupFileName->Length == 0) {
  552. return(STATUS_INVALID_PARAMETER);
  553. }
  554. //
  555. // Tacitly attempt to enable the SE_BACKUP_PRIVILEGE so we can
  556. // can check it on the server side
  557. //
  558. // Note that we make this call on behalf of the client to avoid
  559. // a regression when we check for the privilege on the server
  560. // side -- without this call, 3rd party apps that successfully
  561. // called this API before would fail. Under normal circumstances,
  562. // this is not an encouraged practice.
  563. //
  564. //
  565. // -- This should really be done via ImpersonateSelf()
  566. // and adjusting the thread token
  567. //
  568. ApiStatus = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
  569. TRUE,
  570. FALSE,
  571. &fWasEnabled);
  572. //
  573. // Do the RPC call with an exception handler since RPC will raise an
  574. // exception if anything fails. It is up to us to figure out what
  575. // to do once the exception is raised.
  576. //
  577. RpcTryExcept {
  578. // Call service entry point
  579. status = ElfrBackupELFW (
  580. (IELF_HANDLE) LogHandle,
  581. (PRPC_UNICODE_STRING)BackupFileName);
  582. }
  583. RpcExcept (1) {
  584. status = I_RpcMapWin32Status(RpcExceptionCode());
  585. }
  586. RpcEndExcept
  587. //
  588. // Restore the client's privilege state to what it was before
  589. //
  590. if (NT_SUCCESS(ApiStatus)) {
  591. RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
  592. fWasEnabled,
  593. TRUE,
  594. &fWasEnabled);
  595. }
  596. return (status);
  597. }
  598. NTSTATUS
  599. ElfCloseEventLog (
  600. IN HANDLE LogHandle
  601. )
  602. /*++
  603. Routine Description:
  604. This is the client DLL entry point for the ElfCloseEventLog API.
  605. It closes the RPC binding, and frees any memory allocated for the
  606. handle.
  607. Arguments:
  608. LogHandle - Handle returned from a previous "Open" call.
  609. Return Value:
  610. Returns an NTSTATUS code.
  611. --*/
  612. {
  613. NTSTATUS status;
  614. //
  615. // Do the RPC call with an exception handler since RPC will raise an
  616. // exception if anything fails. It is up to us to figure out what
  617. // to do once the exception is raised.
  618. //
  619. RpcTryExcept {
  620. // Call server
  621. status = ElfrCloseEL (
  622. (PIELF_HANDLE) &LogHandle
  623. );
  624. }
  625. RpcExcept (1) {
  626. status = I_RpcMapWin32Status(RpcExceptionCode());
  627. }
  628. RpcEndExcept
  629. return (status);
  630. }
  631. NTSTATUS
  632. ElfDeregisterEventSource (
  633. IN HANDLE LogHandle
  634. )
  635. /*++
  636. Routine Description:
  637. This is the client DLL entry point for the ElfDeregisterEventSource API.
  638. It closes the RPC binding, and frees any memory allocated for the
  639. handle.
  640. Arguments:
  641. LogHandle - Handle returned from a previous "Open" call.
  642. Return Value:
  643. Returns an NTSTATUS code.
  644. --*/
  645. {
  646. NTSTATUS status;
  647. //
  648. // Do the RPC call with an exception handler since RPC will raise an
  649. // exception if anything fails. It is up to us to figure out what
  650. // to do once the exception is raised.
  651. //
  652. RpcTryExcept {
  653. // Call server
  654. status = ElfrDeregisterEventSource (
  655. (PIELF_HANDLE) &LogHandle
  656. );
  657. }
  658. RpcExcept (1) {
  659. status = I_RpcMapWin32Status(RpcExceptionCode());
  660. }
  661. RpcEndExcept
  662. return (status);
  663. }
  664. NTSTATUS
  665. ElfReadEventLogW (
  666. IN HANDLE LogHandle,
  667. IN ULONG ReadFlags,
  668. IN ULONG RecordNumber,
  669. OUT PVOID Buffer,
  670. IN ULONG NumberOfBytesToRead,
  671. OUT PULONG NumberOfBytesRead,
  672. OUT PULONG MinNumberOfBytesNeeded
  673. )
  674. /*++
  675. Routine Description:
  676. This is the client DLL entry point for the ElfReadEventLog API.
  677. Arguments:
  678. Return Value:
  679. Returns an NTSTATUS code.
  680. --*/
  681. {
  682. NTSTATUS status;
  683. ULONG FlagBits;
  684. //
  685. // Make sure the output pointers are valid
  686. //
  687. if (!Buffer || !NumberOfBytesRead || !MinNumberOfBytesNeeded) {
  688. return(STATUS_INVALID_PARAMETER);
  689. }
  690. //
  691. // Ensure that the ReadFlags we got are valid.
  692. // Make sure that one of each type of bit is set.
  693. //
  694. FlagBits = ReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ);
  695. if ((FlagBits > 2) || (FlagBits == 0)) {
  696. return(STATUS_INVALID_PARAMETER);
  697. }
  698. FlagBits = ReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ);
  699. if ((FlagBits > 8) || (FlagBits == 0)) {
  700. return(STATUS_INVALID_PARAMETER);
  701. }
  702. //
  703. // Do the RPC call with an exception handler since RPC will raise an
  704. // exception if anything fails. It is up to us to figure out what
  705. // to do once the exception is raised.
  706. //
  707. RpcTryExcept {
  708. // Call service
  709. status = ElfrReadELW (
  710. (IELF_HANDLE) LogHandle,
  711. ReadFlags,
  712. RecordNumber,
  713. NumberOfBytesToRead,
  714. Buffer,
  715. NumberOfBytesRead,
  716. MinNumberOfBytesNeeded
  717. );
  718. }
  719. RpcExcept (1) {
  720. status = I_RpcMapWin32Status(RpcExceptionCode());
  721. }
  722. RpcEndExcept
  723. // Return status and bytes read/required.
  724. return (status);
  725. }
  726. NTSTATUS
  727. ElfReportEventW (
  728. IN HANDLE LogHandle,
  729. IN USHORT EventType,
  730. IN USHORT EventCategory OPTIONAL,
  731. IN ULONG EventID,
  732. IN PSID UserSid,
  733. IN USHORT NumStrings,
  734. IN ULONG DataSize,
  735. IN PUNICODE_STRING *Strings,
  736. IN PVOID Data,
  737. IN USHORT Flags,
  738. IN OUT PULONG RecordNumber OPTIONAL,
  739. IN OUT PULONG TimeWritten OPTIONAL
  740. )
  741. /*++
  742. Routine Description:
  743. This is the client DLL entry point for the ElfReportEvent API.
  744. Arguments:
  745. Return Value:
  746. Returns an NTSTATUS code.
  747. Note:
  748. The last three parameters (Flags, RecordNumber and TimeWritten) are
  749. designed to be used by Security Auditing for the implementation of
  750. paired events (associating a file open event with the subsequent file
  751. close). This will not be implemented in Product 1, but the API is
  752. defined to allow easier support of this in a later release.
  753. --*/
  754. {
  755. NTSTATUS status;
  756. PUNICODE_STRING pComputerNameU;
  757. LARGE_INTEGER Time;
  758. ULONG EventTime;
  759. //
  760. // Generate the time of the event. This is done on the client side
  761. // since that is where the event occurred.
  762. //
  763. NtQuerySystemTime(&Time);
  764. RtlTimeToSecondsSince1970(&Time,
  765. &EventTime
  766. );
  767. //
  768. // Generate the ComputerName of the client.
  769. // We have to do this in the client side since this call may be
  770. // remoted to another server and we would not necessarily have
  771. // the computer name there.
  772. //
  773. pComputerNameU = TmpGetComputerNameW();
  774. //
  775. // Do the RPC call with an exception handler since RPC will raise an
  776. // exception if anything fails. It is up to us to figure out what
  777. // to do once the exception is raised.
  778. //
  779. RpcTryExcept {
  780. // Call service
  781. status = ElfrReportEventW (
  782. (IELF_HANDLE) LogHandle,
  783. EventTime,
  784. EventType,
  785. EventCategory,
  786. EventID,
  787. NumStrings,
  788. DataSize,
  789. (PRPC_UNICODE_STRING)pComputerNameU,
  790. UserSid,
  791. (PRPC_UNICODE_STRING *)Strings,
  792. Data,
  793. Flags,
  794. RecordNumber,
  795. TimeWritten
  796. );
  797. }
  798. RpcExcept (1) {
  799. status = I_RpcMapWin32Status(RpcExceptionCode());
  800. }
  801. RpcEndExcept
  802. return (status);
  803. }
  804. //
  805. // ANSI APIs
  806. //
  807. NTSTATUS
  808. ElfOpenEventLogA (
  809. IN PANSI_STRING UNCServerName,
  810. IN PANSI_STRING LogName,
  811. OUT PHANDLE LogHandle
  812. )
  813. /*++
  814. Routine Description:
  815. This is the client DLL entry point for the ElfOpenEventLog API.
  816. It creates an RPC binding for the server specified, and stores that
  817. and additional data away. It returns a handle to the caller that can
  818. be used to later on access the handle-specific information.
  819. Arguments:
  820. UNCServerName - Server with which to bind for subsequent operations.
  821. LogName - Supplies the name of the module for the logfile to
  822. associate with this handle.
  823. LogHandle - Location where log handle is to be returned.
  824. Return Value:
  825. Returns an NTSTATUS code and, if no error, a handle that can be used
  826. for subsequent Elf API calls.
  827. --*/
  828. {
  829. NTSTATUS status = STATUS_SUCCESS;
  830. NTSTATUS ApiStatus;
  831. ANSI_STRING RegModuleName;
  832. EVENTLOG_HANDLE_A ServerNameString;
  833. BOOLEAN fWasEnabled = FALSE;
  834. BOOL fIsSecurityLog;
  835. //
  836. // Make sure input & output pointers are valid
  837. //
  838. if (!LogHandle || !LogName || LogName->Length == 0) {
  839. return(STATUS_INVALID_PARAMETER);
  840. }
  841. if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) {
  842. ServerNameString = UNCServerName->Buffer;
  843. } else {
  844. ServerNameString = NULL;
  845. }
  846. RtlInitAnsiString( &RegModuleName, ELF_APPLICATION_MODULE_NAME_ASCII );
  847. // Call service via RPC. Pass in major and minor version numbers.
  848. *LogHandle = NULL; // Must be NULL so RPC fills it in
  849. fIsSecurityLog = (_stricmp(ELF_SECURITY_MODULE_NAME_ASCII, LogName->Buffer) == 0);
  850. if (fIsSecurityLog) {
  851. //
  852. // Tacitly attempt to enable the SE_SECURITY_PRIVILEGE so we can
  853. // can check it on the server side. We ignore the return value
  854. // because it's possible for this call to fail here but for the
  855. // user to have this privilege if the log is on a remote server
  856. //
  857. // Note that we make this call on behalf of the client to avoid
  858. // a regression when we check for the privilege on the server
  859. // side -- without this call, 3rd party apps that successfully
  860. // called this API before would fail. Under normal circumstances,
  861. // this is not an encouraged practice.
  862. //
  863. //
  864. // -- This should really be done via ImpersonateSelf()
  865. // and adjusting the thread token
  866. //
  867. ApiStatus = RtlAdjustPrivilege(SE_SECURITY_PRIVILEGE,
  868. TRUE,
  869. FALSE,
  870. &fWasEnabled);
  871. }
  872. //
  873. // Do the RPC call with an exception handler since RPC will raise an
  874. // exception if anything fails. It is up to us to figure out what
  875. // to do once the exception is raised.
  876. //
  877. RpcTryExcept {
  878. status = ElfrOpenELA (
  879. ServerNameString,
  880. (PRPC_STRING) LogName,
  881. (PRPC_STRING) &RegModuleName,
  882. ELF_VERSION_MAJOR,
  883. ELF_VERSION_MINOR,
  884. (PIELF_HANDLE) LogHandle);
  885. }
  886. RpcExcept (1) {
  887. status = I_RpcMapWin32Status(RpcExceptionCode());
  888. }
  889. RpcEndExcept
  890. if (fIsSecurityLog && NT_SUCCESS(ApiStatus)) {
  891. //
  892. // Restore the state
  893. //
  894. RtlAdjustPrivilege(SE_SECURITY_PRIVILEGE,
  895. fWasEnabled,
  896. FALSE,
  897. &fWasEnabled);
  898. }
  899. return (status);
  900. }
  901. NTSTATUS
  902. ElfRegisterEventSourceA (
  903. IN PANSI_STRING UNCServerName,
  904. IN PANSI_STRING ModuleName,
  905. OUT PHANDLE LogHandle
  906. )
  907. /*++
  908. Routine Description:
  909. This is the client DLL entry point for the ElfOpenEventLog API.
  910. It creates an RPC binding for the server specified, and stores that
  911. and additional data away. It returns a handle to the caller that can
  912. be used to later on access the handle-specific information.
  913. Arguments:
  914. UNCServerName - Server with which to bind for subsequent operations.
  915. ModuleName - Supplies the name of the module to associate with
  916. this handle.
  917. LogHandle - Location where log handle is to be returned.
  918. Return Value:
  919. Returns an NTSTATUS code and, if no error, a handle that can be used
  920. for subsequent Elf API calls.
  921. --*/
  922. {
  923. NTSTATUS status = STATUS_SUCCESS;
  924. ANSI_STRING RegModuleName;
  925. EVENTLOG_HANDLE_A ServerNameString;
  926. //
  927. // Make sure input & output pointers are valid
  928. //
  929. if (!LogHandle || !ModuleName || ModuleName->Length == 0) {
  930. return(STATUS_INVALID_PARAMETER);
  931. }
  932. if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) {
  933. ServerNameString = UNCServerName->Buffer;
  934. } else {
  935. ServerNameString = NULL;
  936. }
  937. RtlInitAnsiString( &RegModuleName, ELF_APPLICATION_MODULE_NAME_ASCII );
  938. if ( NT_SUCCESS (status) ) {
  939. // Call service via RPC. Pass in major and minor version numbers.
  940. *LogHandle = NULL; // Must be NULL so RPC fills it in
  941. //
  942. // Do the RPC call with an exception handler since RPC will raise an
  943. // exception if anything fails. It is up to us to figure out what
  944. // to do once the exception is raised.
  945. //
  946. RpcTryExcept {
  947. status = ElfrRegisterEventSourceA (
  948. ServerNameString,
  949. (PRPC_STRING)ModuleName,
  950. (PRPC_STRING)&RegModuleName,
  951. ELF_VERSION_MAJOR,
  952. ELF_VERSION_MINOR,
  953. (PIELF_HANDLE) LogHandle
  954. );
  955. }
  956. RpcExcept (1) {
  957. status = I_RpcMapWin32Status(RpcExceptionCode());
  958. }
  959. RpcEndExcept
  960. }
  961. return (status);
  962. }
  963. NTSTATUS
  964. ElfOpenBackupEventLogA (
  965. IN PANSI_STRING UNCServerName,
  966. IN PANSI_STRING FileName,
  967. OUT PHANDLE LogHandle
  968. )
  969. /*++
  970. Routine Description:
  971. This is the client DLL entry point for the ElfOpenBackupEventLog API.
  972. It creates an RPC binding for the server specified, and stores that
  973. and additional data away. It returns a handle to the caller that can
  974. be used to later on access the handle-specific information.
  975. Arguments:
  976. UNCServerName - Server with which to bind for subsequent operations.
  977. FileName - Supplies the filename of the logfile to associate with
  978. this handle.
  979. LogHandle - Location where log handle is to be returned.
  980. Return Value:
  981. Returns an NTSTATUS code and, if no error, a handle that can be used
  982. for subsequent Elf API calls.
  983. --*/
  984. {
  985. EVENTLOG_HANDLE_A ServerNameString;
  986. NTSTATUS status;
  987. //
  988. // Make sure input & output pointers are valid
  989. //
  990. if (!LogHandle || !FileName || FileName->Length == 0) {
  991. return(STATUS_INVALID_PARAMETER);
  992. }
  993. if ((UNCServerName != NULL) && (UNCServerName->Length != 0)) {
  994. ServerNameString = UNCServerName->Buffer;
  995. } else {
  996. ServerNameString = NULL;
  997. }
  998. // Call service via RPC. Pass in major and minor version numbers.
  999. *LogHandle = NULL; // Must be NULL so RPC fills it in
  1000. //
  1001. // Do the RPC call with an exception handler since RPC will raise an
  1002. // exception if anything fails. It is up to us to figure out what
  1003. // to do once the exception is raised.
  1004. //
  1005. RpcTryExcept {
  1006. status = ElfrOpenBELA (
  1007. ServerNameString,
  1008. (PRPC_STRING)FileName,
  1009. ELF_VERSION_MAJOR,
  1010. ELF_VERSION_MINOR,
  1011. (PIELF_HANDLE) LogHandle
  1012. );
  1013. }
  1014. RpcExcept (1) {
  1015. status = I_RpcMapWin32Status(RpcExceptionCode());
  1016. }
  1017. RpcEndExcept
  1018. return (status);
  1019. }
  1020. NTSTATUS
  1021. ElfClearEventLogFileA (
  1022. IN HANDLE LogHandle,
  1023. IN PANSI_STRING BackupFileName
  1024. )
  1025. /*++
  1026. Routine Description:
  1027. This is the client DLL entry point for the ElfClearEventLogFile API.
  1028. The call is passed to the eventlog service on the appropriate server
  1029. identified by LogHandle.
  1030. Arguments:
  1031. LogHandle - Handle returned from a previous "Open" call. This is
  1032. used to identify the module and the server.
  1033. BackupFileName - Name of the file to back up the current log file.
  1034. NULL implies not to back up the file.
  1035. Return Value:
  1036. Returns an NTSTATUS code.
  1037. --*/
  1038. {
  1039. NTSTATUS status;
  1040. //
  1041. // Do the RPC call with an exception handler since RPC will raise an
  1042. // exception if anything fails. It is up to us to figure out what
  1043. // to do once the exception is raised.
  1044. //
  1045. RpcTryExcept {
  1046. // Call service entry point
  1047. status = ElfrClearELFA (
  1048. (IELF_HANDLE) LogHandle,
  1049. (PRPC_STRING)BackupFileName
  1050. );
  1051. }
  1052. RpcExcept (1) {
  1053. status = I_RpcMapWin32Status(RpcExceptionCode());
  1054. }
  1055. RpcEndExcept
  1056. return (status);
  1057. }
  1058. NTSTATUS
  1059. ElfBackupEventLogFileA (
  1060. IN HANDLE LogHandle,
  1061. IN PANSI_STRING BackupFileName
  1062. )
  1063. /*++
  1064. Routine Description:
  1065. This is the client DLL entry point for the ElfBackupEventLogFile API.
  1066. The call is passed to the eventlog service on the appropriate server
  1067. identified by LogHandle.
  1068. Arguments:
  1069. LogHandle - Handle returned from a previous "Open" call. This is
  1070. used to identify the module and the server.
  1071. BackupFileName - Name of the file to back up the current log file.
  1072. Return Value:
  1073. Returns an NTSTATUS code.
  1074. --*/
  1075. {
  1076. NTSTATUS status;
  1077. NTSTATUS ApiStatus;
  1078. BOOLEAN fWasEnabled;
  1079. //
  1080. // Make sure input pointers are valid
  1081. //
  1082. if (!BackupFileName || BackupFileName->Length == 0) {
  1083. return(STATUS_INVALID_PARAMETER);
  1084. }
  1085. //
  1086. // Tacitly attempt to enable the SE_BACKUP_PRIVILEGE so we can
  1087. // can check it on the server side
  1088. //
  1089. // Note that we make this call on behalf of the client to avoid
  1090. // a regression when we check for the privilege on the server
  1091. // side -- without this call, 3rd party apps that successfully
  1092. // called this API before would fail. Under normal circumstances,
  1093. // this is not an encouraged practice.
  1094. //
  1095. //
  1096. // -- This should really be done via ImpersonateSelf()
  1097. // and adjusting the thread token
  1098. //
  1099. ApiStatus = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
  1100. TRUE,
  1101. FALSE,
  1102. &fWasEnabled);
  1103. //
  1104. // Do the RPC call with an exception handler since RPC will raise an
  1105. // exception if anything fails. It is up to us to figure out what
  1106. // to do once the exception is raised.
  1107. //
  1108. RpcTryExcept {
  1109. // Call service entry point
  1110. status = ElfrBackupELFA (
  1111. (IELF_HANDLE) LogHandle,
  1112. (PRPC_STRING)BackupFileName
  1113. );
  1114. }
  1115. RpcExcept (1) {
  1116. status = I_RpcMapWin32Status(RpcExceptionCode());
  1117. }
  1118. RpcEndExcept
  1119. //
  1120. // Restore the client's privilege state to what it was before
  1121. //
  1122. if (NT_SUCCESS(ApiStatus)) {
  1123. RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
  1124. fWasEnabled,
  1125. TRUE,
  1126. &fWasEnabled);
  1127. }
  1128. return (status);
  1129. }
  1130. NTSTATUS
  1131. ElfReadEventLogA (
  1132. IN HANDLE LogHandle,
  1133. IN ULONG ReadFlags,
  1134. IN ULONG RecordNumber,
  1135. OUT PVOID Buffer,
  1136. IN ULONG NumberOfBytesToRead,
  1137. OUT PULONG NumberOfBytesRead,
  1138. OUT PULONG MinNumberOfBytesNeeded
  1139. )
  1140. /*++
  1141. Routine Description:
  1142. This is the client DLL entry point for the ElfReadEventLog API.
  1143. Arguments:
  1144. Return Value:
  1145. Returns an NTSTATUS code.
  1146. --*/
  1147. {
  1148. NTSTATUS status;
  1149. ULONG FlagBits;
  1150. //
  1151. // Make sure the output pointers are valid
  1152. //
  1153. if (!Buffer || !NumberOfBytesRead || !MinNumberOfBytesNeeded) {
  1154. return(STATUS_INVALID_PARAMETER);
  1155. }
  1156. //
  1157. // Ensure that the ReadFlags we got are valid.
  1158. // Make sure that one of each type of bit is set.
  1159. //
  1160. FlagBits = ReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ);
  1161. if ( (FlagBits == (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ))
  1162. || (FlagBits == 0)) {
  1163. return(STATUS_INVALID_PARAMETER);
  1164. }
  1165. FlagBits = ReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ);
  1166. if ( (FlagBits == (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ))
  1167. || (FlagBits == 0)) {
  1168. return(STATUS_INVALID_PARAMETER);
  1169. }
  1170. //
  1171. // Do the RPC call with an exception handler since RPC will raise an
  1172. // exception if anything fails. It is up to us to figure out what
  1173. // to do once the exception is raised.
  1174. //
  1175. RpcTryExcept {
  1176. // Call service
  1177. status = ElfrReadELA (
  1178. (IELF_HANDLE) LogHandle,
  1179. ReadFlags,
  1180. RecordNumber,
  1181. NumberOfBytesToRead,
  1182. Buffer,
  1183. NumberOfBytesRead,
  1184. MinNumberOfBytesNeeded
  1185. );
  1186. }
  1187. RpcExcept (1) {
  1188. status = I_RpcMapWin32Status(RpcExceptionCode());
  1189. }
  1190. RpcEndExcept
  1191. // Return status and bytes read/required.
  1192. return (status);
  1193. }
  1194. NTSTATUS
  1195. ElfReportEventA (
  1196. IN HANDLE LogHandle,
  1197. IN USHORT EventType,
  1198. IN USHORT EventCategory OPTIONAL,
  1199. IN ULONG EventID,
  1200. IN PSID UserSid,
  1201. IN USHORT NumStrings,
  1202. IN ULONG DataSize,
  1203. IN PANSI_STRING *Strings,
  1204. IN PVOID Data,
  1205. IN USHORT Flags,
  1206. IN OUT PULONG RecordNumber OPTIONAL,
  1207. IN OUT PULONG TimeWritten OPTIONAL
  1208. )
  1209. /*++
  1210. Routine Description:
  1211. This is the client DLL entry point for the ElfReportEvent API.
  1212. Arguments:
  1213. Return Value:
  1214. Returns an NTSTATUS code.
  1215. Note:
  1216. The last three parameters (Flags, RecordNumber and TimeWritten) are
  1217. designed to be used by Security Auditing for the implementation of
  1218. paired events (associating a file open event with the subsequent file
  1219. close). This will not be implemented in Product 1, but the API is
  1220. defined to allow easier support of this in a later release.
  1221. --*/
  1222. {
  1223. NTSTATUS status;
  1224. PANSI_STRING pComputerNameA;
  1225. LARGE_INTEGER Time;
  1226. ULONG EventTime;
  1227. //
  1228. // Generate the time of the event. This is done on the client side
  1229. // since that is where the event occurred.
  1230. //
  1231. NtQuerySystemTime(&Time);
  1232. RtlTimeToSecondsSince1970(&Time,
  1233. &EventTime
  1234. );
  1235. //
  1236. // Generate the ComputerName of the client.
  1237. // We have to do this in the client side since this call may be
  1238. // remoted to another server and we would not necessarily have
  1239. // the computer name there.
  1240. //
  1241. pComputerNameA = TmpGetComputerNameA();
  1242. //
  1243. // Do the RPC call with an exception handler since RPC will raise an
  1244. // exception if anything fails. It is up to us to figure out what
  1245. // to do once the exception is raised.
  1246. //
  1247. RpcTryExcept {
  1248. // Call service
  1249. status = ElfrReportEventA (
  1250. (IELF_HANDLE) LogHandle,
  1251. EventTime,
  1252. EventType,
  1253. EventCategory,
  1254. EventID,
  1255. NumStrings,
  1256. DataSize,
  1257. (PRPC_STRING)pComputerNameA,
  1258. UserSid,
  1259. (PRPC_STRING*)Strings,
  1260. Data,
  1261. Flags,
  1262. RecordNumber,
  1263. TimeWritten
  1264. );
  1265. }
  1266. RpcExcept (1) {
  1267. status = I_RpcMapWin32Status(RpcExceptionCode());
  1268. }
  1269. RpcEndExcept
  1270. return (status);
  1271. }
  1272. /****
  1273. @func NTSTATUS | ElfRegisterClusterSvc| The cluster service registers
  1274. itself with the event log service at initialization by calling this api.
  1275. @parm IN PUNICODE_STRING | UNCServerName | Inidicates the server on which the
  1276. cluster service will register with the eventlog service. This must
  1277. be the local node.
  1278. @parm OUT PULONG | pulSize | A pointer to a long that returns the size of the
  1279. packed event information structure that is returned.
  1280. @parm OUT PPACKEDEVENTINFO | *ppPackedEventInfo| A pointer to the packed event information
  1281. structure for propagation is returned via this parameter.
  1282. @comm The elf client validates parameters and called the servier entry point.
  1283. @rdesc Returns a result code. ERROR_SUCCESS on success.
  1284. @xref <f ElfrRegisterClusterSvc>
  1285. ****/
  1286. NTSTATUS
  1287. ElfRegisterClusterSvc (
  1288. IN PUNICODE_STRING UNCServerName,
  1289. OUT PULONG pulSize,
  1290. OUT PPACKEDEVENTINFO *ppPackedEventInfo
  1291. )
  1292. {
  1293. EVENTLOG_HANDLE_W ServerNameString;
  1294. NTSTATUS status;
  1295. if ((UNCServerName != NULL) && (UNCServerName->Length != 0))
  1296. {
  1297. ServerNameString = UNCServerName->Buffer;
  1298. }
  1299. else
  1300. {
  1301. ServerNameString = NULL;
  1302. }
  1303. //
  1304. // Do the RPC call with an exception handler since RPC will raise an
  1305. // exception if anything fails. It is up to us to figure out what
  1306. // to do once the exception is raised.
  1307. //
  1308. RpcTryExcept {
  1309. // Call service
  1310. status = ElfrRegisterClusterSvc (ServerNameString, pulSize,
  1311. (PBYTE *)ppPackedEventInfo);
  1312. }
  1313. RpcExcept (1) {
  1314. status = I_RpcMapWin32Status(RpcExceptionCode());
  1315. }
  1316. RpcEndExcept
  1317. return(status);
  1318. }
  1319. /****
  1320. @func NTSTATUS | ElfDeregisterClusterSvc| Before stopping the cluster
  1321. service deregisters itself for propagation of events from the
  1322. eventlog service.
  1323. @parm IN PUNICODE_STRING | UNCServerName | Inidicates the server on which the
  1324. cluster service will register with the eventlog service. This must
  1325. be on the local node.
  1326. @comm The elf client forwards this to the appropriate eventlog server entry point.
  1327. @rdesc Returns a result code. ERROR_SUCCESS on success.
  1328. @xref <f ElfDeregisterClusterSvc> <f ElfrDeregisterClusterSvc>
  1329. ****/
  1330. NTSTATUS
  1331. ElfDeregisterClusterSvc(
  1332. IN PUNICODE_STRING UNCServerName
  1333. )
  1334. {
  1335. NTSTATUS status;
  1336. EVENTLOG_HANDLE_W ServerNameString;
  1337. if ((UNCServerName != NULL) && (UNCServerName->Length != 0))
  1338. {
  1339. ServerNameString = UNCServerName->Buffer;
  1340. }
  1341. else
  1342. {
  1343. ServerNameString = NULL;
  1344. }
  1345. //
  1346. // Do the RPC call with an exception handler since RPC will raise an
  1347. // exception if anything fails. It is up to us to figure out what
  1348. // to do once the exception is raised.
  1349. //
  1350. RpcTryExcept {
  1351. // Call service
  1352. status = ElfrDeregisterClusterSvc (ServerNameString);
  1353. }
  1354. RpcExcept (1) {
  1355. status = I_RpcMapWin32Status(RpcExceptionCode());
  1356. }
  1357. RpcEndExcept
  1358. return(status);
  1359. }
  1360. /****
  1361. @func NTSTATUS | ElfWriteClusterEvents| The cluster service calls this
  1362. api to log events reported at other nodes of the cluster.
  1363. @parm IN EVENTLOG_HANDLE_W | UNCServerName | Not used.
  1364. @parm IN ULONG | ulSize | The size of the packed event information structure.
  1365. @parm IN PACKEDEVENTINFO | pPackedEventInfo| A pointer to the packed event information
  1366. structure for propagation.
  1367. @comm The elf client validates the parameters and forwards this to the appropriate
  1368. entry point in the eventlog server.
  1369. @rdesc Returns a result code. ERROR_SUCCESS on success.
  1370. @xref
  1371. ****/
  1372. NTSTATUS
  1373. ElfWriteClusterEvents(
  1374. IN PUNICODE_STRING UNCServerName,
  1375. IN ULONG ulSize,
  1376. IN PPACKEDEVENTINFO pPackedEventInfo)
  1377. {
  1378. NTSTATUS status;
  1379. EVENTLOG_HANDLE_W ServerNameString;
  1380. //validate input parameters
  1381. if (!pPackedEventInfo || !ulSize || (pPackedEventInfo->ulSize != ulSize))
  1382. return(STATUS_INVALID_PARAMETER);
  1383. if ((UNCServerName != NULL) && (UNCServerName->Length != 0))
  1384. {
  1385. ServerNameString = UNCServerName->Buffer;
  1386. }
  1387. else
  1388. {
  1389. ServerNameString = NULL;
  1390. }
  1391. //
  1392. // Do the RPC call with an exception handler since RPC will raise an
  1393. // exception if anything fails. It is up to us to figure out what
  1394. // to do once the exception is raised.
  1395. //
  1396. RpcTryExcept {
  1397. // Call service
  1398. status = ElfrWriteClusterEvents (ServerNameString, ulSize,
  1399. (PBYTE)pPackedEventInfo);
  1400. }
  1401. RpcExcept (1) {
  1402. status = I_RpcMapWin32Status(RpcExceptionCode());
  1403. }
  1404. RpcEndExcept
  1405. return(status);
  1406. }
  1407. NTSTATUS
  1408. ElfFlushEventLog (
  1409. IN HANDLE LogHandle
  1410. )
  1411. /*++
  1412. Routine Description:
  1413. This is the client DLL entry point for the ElfFlushEventLog API.
  1414. Arguments:
  1415. LogHandle - Handle returned from a previous "Open" call.
  1416. Return Value:
  1417. Returns an NTSTATUS code.
  1418. --*/
  1419. {
  1420. NTSTATUS status;
  1421. //
  1422. // Do the RPC call with an exception handler since RPC will raise an
  1423. // exception if anything fails. It is up to us to figure out what
  1424. // to do once the exception is raised.
  1425. //
  1426. RpcTryExcept {
  1427. // Call server
  1428. status = ElfrFlushEL (
  1429. (IELF_HANDLE) LogHandle
  1430. );
  1431. }
  1432. RpcExcept (1) {
  1433. status = I_RpcMapWin32Status(RpcExceptionCode());
  1434. }
  1435. RpcEndExcept
  1436. return (status);
  1437. }