f5f88b32e468cc3c09b9c74e58926f50dda82fc6
[reactos.git] / reactos / base / services / eventlog / rpc.c
1 /*
2 * PROJECT: ReactOS kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: services/eventlog/rpc.c
5 * PURPOSE: Event logging service
6 * COPYRIGHT: Copyright 2005 Saveliy Tretiakov
7 * Copyright 2008 Michael Martin
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "eventlog.h"
13
14 LIST_ENTRY LogHandleListHead;
15
16 /* FUNCTIONS ****************************************************************/
17
18 DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
19 {
20 RPC_STATUS Status;
21
22 InitializeListHead(&LogHandleListHead);
23
24 Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\EventLog", NULL);
25 if (Status != RPC_S_OK)
26 {
27 DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
28 return 0;
29 }
30
31 Status = RpcServerRegisterIf(eventlog_v0_0_s_ifspec, NULL, NULL);
32 if (Status != RPC_S_OK)
33 {
34 DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status);
35 return 0;
36 }
37
38 Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
39 if (Status != RPC_S_OK)
40 {
41 DPRINT("RpcServerListen() failed (Status %lx)\n", Status);
42 }
43
44 return 0;
45 }
46
47 PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
48 {
49 PLOGHANDLE lpLogHandle;
50 PLOGFILE currentLogFile = NULL;
51 INT i, LogsActive;
52 PEVENTSOURCE pEventSource;
53
54 DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
55
56 lpLogHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE)
57 + ((wcslen(Name) + 1) * sizeof(WCHAR)));
58 if (!lpLogHandle)
59 {
60 DPRINT1("Failed to allocate Heap!\n");
61 return NULL;
62 }
63
64 wcscpy(lpLogHandle->szName, Name);
65
66 /* Get the number of Log Files the EventLog service found */
67 LogsActive = LogfListItemCount();
68 if (LogsActive == 0)
69 {
70 DPRINT1("EventLog service reports no log files!\n");
71 goto Cleanup;
72 }
73
74 /* If Creating, default to the Application Log in case we fail, as documented on MSDN */
75 if (Create == TRUE)
76 {
77 pEventSource = GetEventSourceByName(Name);
78 DPRINT("EventSource: %p\n", pEventSource);
79 if (pEventSource)
80 {
81 DPRINT("EventSource LogFile: %p\n", pEventSource->LogFile);
82 lpLogHandle->LogFile = pEventSource->LogFile;
83 }
84 else
85 {
86 DPRINT("EventSource LogFile: Application log file\n");
87 lpLogHandle->LogFile = LogfListItemByName(L"Application");
88 }
89
90 DPRINT("LogHandle LogFile: %p\n", lpLogHandle->LogFile);
91 }
92 else
93 {
94 lpLogHandle->LogFile = NULL;
95
96 for (i = 1; i <= LogsActive; i++)
97 {
98 currentLogFile = LogfListItemByIndex(i);
99
100 if (_wcsicmp(Name, currentLogFile->LogName) == 0)
101 {
102 lpLogHandle->LogFile = LogfListItemByIndex(i);
103 lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
104 break;
105 }
106 }
107
108 /* Use the application log if the desired log does not exist */
109 if (lpLogHandle->LogFile == NULL)
110 {
111 lpLogHandle->LogFile = LogfListItemByName(L"Application");
112 lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
113 }
114 }
115
116 if (!lpLogHandle->LogFile)
117 goto Cleanup;
118
119 /* Append log handle */
120 InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry);
121
122 return lpLogHandle;
123
124 Cleanup:
125 HeapFree(GetProcessHeap(), 0, lpLogHandle);
126
127 return NULL;
128 }
129
130 PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
131 {
132 PLOGHANDLE lpLogHandle;
133
134 if (IsListEmpty(&LogHandleListHead))
135 {
136 return NULL;
137 }
138
139 lpLogHandle = CONTAINING_RECORD((PLOGHANDLE)EventLogHandle, LOGHANDLE, LogHandleListEntry);
140
141 return lpLogHandle;
142 }
143
144 BOOL ElfDeleteEventLogHandle(IELF_HANDLE EventLogHandle)
145 {
146 PLOGHANDLE lpLogHandle = (PLOGHANDLE)EventLogHandle;
147 if (!ElfGetLogHandleEntryByHandle(lpLogHandle))
148 {
149 return FALSE;
150 }
151
152 RemoveEntryList(&lpLogHandle->LogHandleListEntry);
153 HeapFree(GetProcessHeap(),0,lpLogHandle);
154
155 return TRUE;
156 }
157
158 /* Function 0 */
159 NTSTATUS ElfrClearELFW(
160 IELF_HANDLE LogHandle,
161 PRPC_UNICODE_STRING BackupFileName)
162 {
163 PLOGHANDLE lpLogHandle;
164 PLOGFILE lpLogFile;
165
166 lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
167 if (!lpLogHandle)
168 {
169 return STATUS_INVALID_HANDLE;
170 }
171
172 lpLogFile = lpLogHandle->LogFile;
173
174 if (BackupFileName->Length > 0)
175 {
176 /* FIXME: Write a backup file */
177 }
178
179 LogfInitializeNew(lpLogFile);
180
181 return STATUS_SUCCESS;
182 }
183
184
185 /* Function 1 */
186 NTSTATUS ElfrBackupELFW(
187 IELF_HANDLE LogHandle,
188 PRPC_UNICODE_STRING BackupFileName)
189 {
190 UNIMPLEMENTED;
191 return STATUS_NOT_IMPLEMENTED;
192 }
193
194 /* Function 2 */
195 NTSTATUS ElfrCloseEL(
196 IELF_HANDLE *LogHandle)
197 {
198 if (!ElfDeleteEventLogHandle(*LogHandle))
199 {
200 return STATUS_INVALID_HANDLE;
201 }
202
203 return STATUS_SUCCESS;
204 }
205
206
207 /* Function 3 */
208 NTSTATUS ElfrDeregisterEventSource(
209 IELF_HANDLE *LogHandle)
210 {
211 if (!ElfDeleteEventLogHandle(*LogHandle))
212 {
213 return STATUS_INVALID_HANDLE;
214 }
215
216 return STATUS_SUCCESS;
217 }
218
219
220 /* Function 4 */
221 NTSTATUS ElfrNumberOfRecords(
222 IELF_HANDLE LogHandle,
223 DWORD *NumberOfRecords)
224 {
225 PLOGHANDLE lpLogHandle;
226 PLOGFILE lpLogFile;
227
228 lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
229 if (!lpLogHandle)
230 {
231 return STATUS_INVALID_HANDLE;
232 }
233
234 lpLogFile = lpLogHandle->LogFile;
235
236 if (lpLogFile->Header.OldestRecordNumber == 0)
237 *NumberOfRecords = 0;
238 else
239 *NumberOfRecords = lpLogFile->Header.CurrentRecordNumber -
240 lpLogFile->Header.OldestRecordNumber;
241
242 return STATUS_SUCCESS;
243 }
244
245
246 /* Function 5 */
247 NTSTATUS ElfrOldestRecord(
248 IELF_HANDLE LogHandle,
249 DWORD *OldestRecordNumber)
250 {
251 PLOGHANDLE lpLogHandle;
252
253 lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
254 if (!lpLogHandle)
255 {
256 return STATUS_INVALID_HANDLE;
257 }
258
259 if (!OldestRecordNumber)
260 {
261 return STATUS_INVALID_PARAMETER;
262 }
263
264 *OldestRecordNumber = 0;
265 *OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile);
266 return STATUS_SUCCESS;
267 }
268
269
270 /* Function 6 */
271 NTSTATUS ElfrChangeNotify(
272 IELF_HANDLE *LogHandle,
273 RPC_CLIENT_ID ClientId,
274 DWORD Event)
275 {
276 UNIMPLEMENTED;
277 return STATUS_NOT_IMPLEMENTED;
278 }
279
280
281 /* Function 7 */
282 NTSTATUS ElfrOpenELW(
283 EVENTLOG_HANDLE_W UNCServerName,
284 PRPC_UNICODE_STRING ModuleName,
285 PRPC_UNICODE_STRING RegModuleName,
286 DWORD MajorVersion,
287 DWORD MinorVersion,
288 IELF_HANDLE *LogHandle)
289 {
290 if ((MajorVersion != 1) || (MinorVersion != 1))
291 return STATUS_INVALID_PARAMETER;
292
293 /* RegModuleName must be an empty string */
294 if (RegModuleName->Length > 0)
295 return STATUS_INVALID_PARAMETER;
296
297 /*FIXME: UNCServerName must specify the server */
298
299 /*FIXME: Must verify that caller has read access */
300
301 *LogHandle = ElfCreateEventLogHandle(ModuleName->Buffer, FALSE);
302
303 if (*LogHandle == NULL)
304 {
305 return STATUS_INVALID_PARAMETER;
306 }
307
308 return STATUS_SUCCESS;
309 }
310
311
312 /* Function 8 */
313 NTSTATUS ElfrRegisterEventSourceW(
314 EVENTLOG_HANDLE_W UNCServerName,
315 PRPC_UNICODE_STRING ModuleName,
316 PRPC_UNICODE_STRING RegModuleName,
317 DWORD MajorVersion,
318 DWORD MinorVersion,
319 IELF_HANDLE *LogHandle)
320 {
321 DPRINT("ElfrRegisterEventSourceW()\n");
322
323 if ((MajorVersion != 1) || (MinorVersion != 1))
324 return STATUS_INVALID_PARAMETER;
325
326 /* RegModuleName must be an empty string */
327 if (RegModuleName->Length > 0)
328 return STATUS_INVALID_PARAMETER;
329
330 DPRINT("ModuleName: %S\n", ModuleName->Buffer);
331
332 /*FIXME: UNCServerName must specify the server or empty for local */
333
334 /*FIXME: Must verify that caller has write access */
335
336 *LogHandle = ElfCreateEventLogHandle(ModuleName->Buffer, TRUE);
337
338 return STATUS_SUCCESS;
339 }
340
341
342 /* Function 9 */
343 NTSTATUS ElfrOpenBELW(
344 EVENTLOG_HANDLE_W UNCServerName,
345 PRPC_UNICODE_STRING BackupFileName,
346 DWORD MajorVersion,
347 DWORD MinorVersion,
348 IELF_HANDLE *LogHandle)
349 {
350 UNIMPLEMENTED;
351 return STATUS_NOT_IMPLEMENTED;
352 }
353
354
355 /* Function 10 */
356 NTSTATUS ElfrReadELW(
357 IELF_HANDLE LogHandle,
358 DWORD ReadFlags,
359 DWORD RecordOffset,
360 RULONG NumberOfBytesToRead,
361 BYTE *Buffer,
362 DWORD *NumberOfBytesRead,
363 DWORD *MinNumberOfBytesNeeded)
364 {
365 PLOGHANDLE lpLogHandle;
366 DWORD dwError;
367 DWORD RecordNumber;
368
369 lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
370 if (!lpLogHandle)
371 {
372 return STATUS_INVALID_HANDLE;
373 }
374
375 if (!Buffer)
376 return I_RpcMapWin32Status(ERROR_INVALID_PARAMETER);
377
378 /* If sequential read, retrieve the CurrentRecord from this log handle */
379 if (ReadFlags & EVENTLOG_SEQUENTIAL_READ)
380 {
381 RecordNumber = lpLogHandle->CurrentRecord;
382 }
383 else
384 {
385 RecordNumber = RecordOffset;
386 }
387
388 dwError = LogfReadEvent(lpLogHandle->LogFile, ReadFlags, &RecordNumber,
389 NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded);
390
391 /* Update the handles CurrentRecord if success*/
392 if (dwError == ERROR_SUCCESS)
393 {
394 lpLogHandle->CurrentRecord = RecordNumber;
395 }
396
397 return I_RpcMapWin32Status(dwError);
398 }
399
400
401 /* Function 11 */
402 NTSTATUS ElfrReportEventW(
403 IELF_HANDLE LogHandle,
404 DWORD Time,
405 USHORT EventType,
406 USHORT EventCategory,
407 DWORD EventID,
408 USHORT NumStrings,
409 DWORD DataSize,
410 PRPC_UNICODE_STRING ComputerName,
411 PRPC_SID UserSID,
412 PRPC_UNICODE_STRING Strings[],
413 BYTE *Data,
414 USHORT Flags,
415 DWORD *RecordNumber,
416 DWORD *TimeWritten)
417 {
418 USHORT i;
419 PBYTE LogBuffer;
420 PLOGHANDLE lpLogHandle;
421 DWORD lastRec;
422 DWORD recSize;
423 DWORD dwStringsSize = 0;
424 DWORD dwUserSidLength = 0;
425 DWORD dwError = ERROR_SUCCESS;
426 WCHAR *lpStrings;
427 int pos = 0;
428
429 lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
430 if (!lpLogHandle)
431 {
432 return STATUS_INVALID_HANDLE;
433 }
434
435 /* Flags must be 0 */
436 if (Flags)
437 {
438 return STATUS_INVALID_PARAMETER;
439 }
440
441 lastRec = LogfGetCurrentRecord(lpLogHandle->LogFile);
442
443 for (i = 0; i < NumStrings; i++)
444 {
445 switch (EventType)
446 {
447 case EVENTLOG_SUCCESS:
448 DPRINT("Success: %wZ\n", Strings[i]);
449 break;
450
451 case EVENTLOG_ERROR_TYPE:
452 DPRINT("Error: %wZ\n", Strings[i]);
453 break;
454
455 case EVENTLOG_WARNING_TYPE:
456 DPRINT("Warning: %wZ\n", Strings[i]);
457 break;
458
459 case EVENTLOG_INFORMATION_TYPE:
460 DPRINT("Info: %wZ\n", Strings[i]);
461 break;
462
463 default:
464 DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]);
465 break;
466 }
467 dwStringsSize += Strings[i]->Length + sizeof UNICODE_NULL;
468 }
469
470 lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize);
471 if (!lpStrings)
472 {
473 DPRINT1("Failed to allocate heap\n");
474 return STATUS_NO_MEMORY;
475 }
476
477 for (i = 0; i < NumStrings; i++)
478 {
479 CopyMemory(lpStrings + pos, Strings[i]->Buffer, Strings[i]->Length);
480 pos += Strings[i]->Length / sizeof(WCHAR);
481 lpStrings[pos] = UNICODE_NULL;
482 pos += sizeof UNICODE_NULL / sizeof(WCHAR);
483 }
484
485 if (UserSID)
486 dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
487 LogBuffer = LogfAllocAndBuildNewRecord(&recSize,
488 lastRec,
489 EventType,
490 EventCategory,
491 EventID,
492 lpLogHandle->szName,
493 ComputerName->Buffer,
494 dwUserSidLength,
495 UserSID,
496 NumStrings,
497 lpStrings,
498 DataSize,
499 Data);
500
501 dwError = LogfWriteData(lpLogHandle->LogFile, recSize, LogBuffer);
502 if (!dwError)
503 {
504 DPRINT1("ERROR WRITING TO EventLog %S\n", lpLogHandle->LogFile->FileName);
505 }
506
507 LogfFreeRecord(LogBuffer);
508
509 HeapFree(GetProcessHeap(), 0, lpStrings);
510
511 return I_RpcMapWin32Status(dwError);
512 }
513
514
515 /* Function 12 */
516 NTSTATUS ElfrClearELFA(
517 IELF_HANDLE LogHandle,
518 PRPC_STRING BackupFileName)
519 {
520 UNICODE_STRING BackupFileNameW;
521 NTSTATUS Status;
522
523 Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
524 (PANSI_STRING)BackupFileName,
525 TRUE);
526 if (!NT_SUCCESS(Status))
527 return Status;
528
529 Status = ElfrClearELFW(LogHandle,
530 (PRPC_UNICODE_STRING)&BackupFileNameW);
531
532 RtlFreeUnicodeString(&BackupFileNameW);
533
534 return Status;
535 }
536
537
538 /* Function 13 */
539 NTSTATUS ElfrBackupELFA(
540 IELF_HANDLE LogHandle,
541 PRPC_STRING BackupFileName)
542 {
543 UNIMPLEMENTED;
544 return STATUS_NOT_IMPLEMENTED;
545 }
546
547
548 /* Function 14 */
549 NTSTATUS ElfrOpenELA(
550 EVENTLOG_HANDLE_A UNCServerName,
551 PRPC_STRING ModuleName,
552 PRPC_STRING RegModuleName,
553 DWORD MajorVersion,
554 DWORD MinorVersion,
555 IELF_HANDLE *LogHandle)
556 {
557 UNICODE_STRING ModuleNameW;
558 NTSTATUS Status;
559
560 if ((MajorVersion != 1) || (MinorVersion != 1))
561 return STATUS_INVALID_PARAMETER;
562
563 /* RegModuleName must be an empty string */
564 if (RegModuleName->Length > 0)
565 return STATUS_INVALID_PARAMETER;
566
567 Status = RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
568 if (!NT_SUCCESS(Status))
569 return Status;
570
571 /* FIXME: Must verify that caller has read access */
572
573 *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer, FALSE);
574
575 RtlFreeUnicodeString(&ModuleNameW);
576
577 if (*LogHandle == NULL)
578 {
579 return STATUS_INVALID_PARAMETER;
580 }
581
582 return STATUS_SUCCESS;
583 }
584
585
586 /* Function 15 */
587 NTSTATUS ElfrRegisterEventSourceA(
588 EVENTLOG_HANDLE_A UNCServerName,
589 PRPC_STRING ModuleName,
590 PRPC_STRING RegModuleName,
591 DWORD MajorVersion,
592 DWORD MinorVersion,
593 IELF_HANDLE *LogHandle)
594 {
595 UNICODE_STRING ModuleNameW;
596 NTSTATUS Status;
597
598 Status = RtlAnsiStringToUnicodeString(&ModuleNameW,
599 (PANSI_STRING)ModuleName,
600 TRUE);
601 if (!NT_SUCCESS(Status))
602 {
603 DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status);
604 return Status;
605 }
606
607 /* RegModuleName must be an empty string */
608 if (RegModuleName->Length > 0)
609 {
610 RtlFreeUnicodeString(&ModuleNameW);
611 return STATUS_INVALID_PARAMETER;
612 }
613
614 if ((MajorVersion != 1) || (MinorVersion != 1))
615 {
616 RtlFreeUnicodeString(&ModuleNameW);
617 return STATUS_INVALID_PARAMETER;
618 }
619
620 /* FIXME: Must verify that caller has write access */
621
622 *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer,
623 TRUE);
624
625 RtlFreeUnicodeString(&ModuleNameW);
626
627 return STATUS_SUCCESS;
628 }
629
630
631 /* Function 16 */
632 NTSTATUS ElfrOpenBELA(
633 EVENTLOG_HANDLE_A UNCServerName,
634 PRPC_STRING BackupFileName,
635 DWORD MajorVersion,
636 DWORD MinorVersion,
637 IELF_HANDLE *LogHandle)
638 {
639 UNIMPLEMENTED;
640 return STATUS_NOT_IMPLEMENTED;
641 }
642
643
644 /* Function 17 */
645 NTSTATUS ElfrReadELA(
646 IELF_HANDLE LogHandle,
647 DWORD ReadFlags,
648 DWORD RecordOffset,
649 RULONG NumberOfBytesToRead,
650 BYTE *Buffer,
651 DWORD *NumberOfBytesRead,
652 DWORD *MinNumberOfBytesNeeded)
653 {
654 UNIMPLEMENTED;
655 return STATUS_NOT_IMPLEMENTED;
656 }
657
658
659 /* Function 18 */
660 NTSTATUS ElfrReportEventA(
661 IELF_HANDLE LogHandle,
662 DWORD Time,
663 USHORT EventType,
664 USHORT EventCategory,
665 DWORD EventID,
666 USHORT NumStrings,
667 DWORD DataSize,
668 PRPC_STRING ComputerName,
669 PRPC_SID UserSID,
670 PRPC_STRING Strings[],
671 BYTE *Data,
672 USHORT Flags,
673 DWORD *RecordNumber,
674 DWORD *TimeWritten)
675 {
676 UNIMPLEMENTED;
677 return STATUS_NOT_IMPLEMENTED;
678 }
679
680
681 /* Function 19 */
682 NTSTATUS ElfrRegisterClusterSvc(
683 handle_t BindingHandle)
684 {
685 UNIMPLEMENTED;
686 return STATUS_NOT_IMPLEMENTED;
687 }
688
689
690 /* Function 20 */
691 NTSTATUS ElfrDeregisterClusterSvc(
692 handle_t BindingHandle)
693 {
694 UNIMPLEMENTED;
695 return STATUS_NOT_IMPLEMENTED;
696 }
697
698
699 /* Function 21 */
700 NTSTATUS ElfrWriteClusterEvents(
701 handle_t BindingHandle)
702 {
703 UNIMPLEMENTED;
704 return STATUS_NOT_IMPLEMENTED;
705 }
706
707
708 /* Function 22 */
709 NTSTATUS ElfrGetLogInformation(
710 IELF_HANDLE LogHandle,
711 DWORD InfoLevel,
712 BYTE *Buffer,
713 DWORD cbBufSize,
714 DWORD *pcbBytesNeeded)
715 {
716 NTSTATUS Status = STATUS_SUCCESS;
717
718 /* FIXME: check handle first */
719
720 switch (InfoLevel)
721 {
722 case EVENTLOG_FULL_INFO:
723 {
724 LPEVENTLOG_FULL_INFORMATION efi = (LPEVENTLOG_FULL_INFORMATION)Buffer;
725
726 *pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
727 if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION))
728 {
729 return STATUS_BUFFER_TOO_SMALL;
730 }
731
732 efi->dwFull = 0; /* FIXME */
733 }
734 break;
735
736 default:
737 Status = STATUS_INVALID_LEVEL;
738 break;
739 }
740
741 return Status;
742 }
743
744
745 /* Function 23 */
746 NTSTATUS ElfrFlushEL(
747 IELF_HANDLE LogHandle)
748 {
749 UNIMPLEMENTED;
750 return STATUS_NOT_IMPLEMENTED;
751 }
752
753
754 /* Function 24 */
755 NTSTATUS ElfrReportEventAndSourceW(
756 IELF_HANDLE LogHandle,
757 DWORD Time,
758 USHORT EventType,
759 USHORT EventCategory,
760 ULONG EventID,
761 PRPC_UNICODE_STRING SourceName,
762 USHORT NumStrings,
763 DWORD DataSize,
764 PRPC_UNICODE_STRING ComputerName,
765 PRPC_SID UserSID,
766 PRPC_UNICODE_STRING Strings[],
767 BYTE *Data,
768 USHORT Flags,
769 DWORD *RecordNumber,
770 DWORD *TimeWritten)
771 {
772 UNIMPLEMENTED;
773 return STATUS_NOT_IMPLEMENTED;
774 }
775
776
777 void __RPC_FAR *__RPC_USER midl_user_allocate(SIZE_T len)
778 {
779 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
780 }
781
782
783 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
784 {
785 HeapFree(GetProcessHeap(), 0, ptr);
786 }
787
788
789 void __RPC_USER IELF_HANDLE_rundown(IELF_HANDLE LogHandle)
790 {
791 }