ReactOS 0.4.15-dev-7670-g69b08be
eventcreate.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#include <conutils.h>
#include <strsafe.h>
#include "resource.h"
Include dependency graph for eventcreate.c:

Go to the source code of this file.

Classes

struct  _OPTION
 

Macros

#define EVENT_ID_MIN   0
 
#define EVENT_ID_MAX   65535
 
#define APPLICATION_NAME   L"EventCreate"
 
#define MAX_KEY_LENGTH   255
 
#define OPTION_ALLOWED_LIST   0x01
 
#define OPTION_NOT_EMPTY   0x02
 
#define OPTION_TRIM_SPACE   0x04
 
#define OPTION_EXCLUSIVE   0x08
 
#define OPTION_MANDATORY   0x10
 
#define NEW_OPT(Name, Type, Flags, MaxOfInstances, ValueSize, ValueBuffer)    {(Name), (Type), (Flags), (MaxOfInstances), NULL, NULL, 0, (ValueSize), (ValueBuffer)}
 
#define NEW_OPT_EX(Name, Type, Flags, AllowedValues, MaxOfInstances, ValueSize, ValueBuffer)    {(Name), (Type), (Flags), (MaxOfInstances), (AllowedValues), NULL, 0, (ValueSize), (ValueBuffer)}
 
#define OPT_SYSTEM   (Options[1])
 
#define OPT_USER   (Options[2])
 
#define OPT_PASSWD   (Options[3])
 
#define OPT_EVTID   (Options[8])
 

Typedefs

typedef struct _OPTION OPTION
 
typedef struct _OPTIONPOPTION
 
typedef enum _PARSER_ERROR PARSER_ERROR
 
typedef VOID(__cdeclPRINT_ERROR_FUNC) (IN PARSER_ERROR,...)
 

Enumerations

enum  TYPE {
  TYPE_None = 0 , TYPE_Str , TYPE_U32 , TYPE_RENAMEITEM ,
  TYPE_CREATE , TYPE_DELETE , TYPE_MKDIR , TYPE_RMDIR ,
  TYPE_RENAMEFOLDER , TYPE_UPDATEDIR , TYPE_MAX = TYPE_UPDATEDIR
}
 
enum  _PARSER_ERROR {
  Success = 0 , InvalidSyntax , InvalidOption , ValueRequired ,
  ValueIsEmpty , InvalidValue , ValueNotAllowed , TooManySameOption ,
  MandatoryOptionAbsent
}
 

Functions

VOID PrintError (DWORD dwError)
 
static BOOL GetUserToken (OUT PTOKEN_USER *ppUserToken)
 
static LONG InstallEventSource (IN HKEY hEventLogKey, IN LPCWSTR EventLogSource)
 
static BOOL CheckLogOrSourceExistence (IN LPCWSTR UNCServerName OPTIONAL, IN LPCWSTR EventLogName, IN LPCWSTR EventLogSource, IN BOOL AllowAppSources OPTIONAL)
 
static PWSTR TrimLeftRightWhitespace (IN PWSTR String)
 
BOOL DoParse (IN INT argc, IN WCHAR *argv[], IN OUT POPTION Options, IN ULONG NumOptions, IN PRINT_ERROR_FUNC PrintErrorFunc OPTIONAL)
 
static VOID __cdecl PrintParserError (PARSER_ERROR Error,...)
 
int wmain (int argc, WCHAR *argv[])
 

Macro Definition Documentation

◆ APPLICATION_NAME

#define APPLICATION_NAME   L"EventCreate"

Definition at line 108 of file eventcreate.c.

◆ EVENT_ID_MAX

#define EVENT_ID_MAX   65535

Definition at line 102 of file eventcreate.c.

◆ EVENT_ID_MIN

#define EVENT_ID_MIN   0

Definition at line 101 of file eventcreate.c.

◆ MAX_KEY_LENGTH

#define MAX_KEY_LENGTH   255

◆ NEW_OPT

#define NEW_OPT (   Name,
  Type,
  Flags,
  MaxOfInstances,
  ValueSize,
  ValueBuffer 
)     {(Name), (Type), (Flags), (MaxOfInstances), NULL, NULL, 0, (ValueSize), (ValueBuffer)}

Definition at line 684 of file eventcreate.c.

◆ NEW_OPT_EX

#define NEW_OPT_EX (   Name,
  Type,
  Flags,
  AllowedValues,
  MaxOfInstances,
  ValueSize,
  ValueBuffer 
)     {(Name), (Type), (Flags), (MaxOfInstances), (AllowedValues), NULL, 0, (ValueSize), (ValueBuffer)}

Definition at line 687 of file eventcreate.c.

◆ OPT_EVTID

#define OPT_EVTID   (Options[8])

◆ OPT_PASSWD

#define OPT_PASSWD   (Options[3])

◆ OPT_SYSTEM

#define OPT_SYSTEM   (Options[1])

◆ OPT_USER

#define OPT_USER   (Options[2])

◆ OPTION_ALLOWED_LIST

#define OPTION_ALLOWED_LIST   0x01

Definition at line 660 of file eventcreate.c.

◆ OPTION_EXCLUSIVE

#define OPTION_EXCLUSIVE   0x08

Definition at line 663 of file eventcreate.c.

◆ OPTION_MANDATORY

#define OPTION_MANDATORY   0x10

Definition at line 664 of file eventcreate.c.

◆ OPTION_NOT_EMPTY

#define OPTION_NOT_EMPTY   0x02

Definition at line 661 of file eventcreate.c.

◆ OPTION_TRIM_SPACE

#define OPTION_TRIM_SPACE   0x04

Definition at line 662 of file eventcreate.c.

Typedef Documentation

◆ OPTION

◆ PARSER_ERROR

◆ POPTION

typedef struct _OPTION * POPTION

◆ PRINT_ERROR_FUNC

typedef VOID(__cdecl * PRINT_ERROR_FUNC) (IN PARSER_ERROR,...)

Definition at line 723 of file eventcreate.c.

Enumeration Type Documentation

◆ _PARSER_ERROR

Enumerator
Success 
InvalidSyntax 
InvalidOption 
ValueRequired 
ValueIsEmpty 
InvalidValue 
ValueNotAllowed 
TooManySameOption 
MandatoryOptionAbsent 

Definition at line 710 of file eventcreate.c.

711{
712 Success = 0,
@ TooManySameOption
Definition: eventcreate.c:719
@ InvalidOption
Definition: eventcreate.c:714
@ MandatoryOptionAbsent
Definition: eventcreate.c:720
@ InvalidValue
Definition: eventcreate.c:717
@ ValueNotAllowed
Definition: eventcreate.c:718
@ ValueRequired
Definition: eventcreate.c:715
@ InvalidSyntax
Definition: eventcreate.c:713
@ ValueIsEmpty
Definition: eventcreate.c:716
@ Success
Definition: eventcreate.c:712
enum _PARSER_ERROR PARSER_ERROR

◆ TYPE

Enumerator
TYPE_None 
TYPE_Str 
TYPE_U32 
TYPE_RENAMEITEM 
TYPE_CREATE 
TYPE_DELETE 
TYPE_MKDIR 
TYPE_RMDIR 
TYPE_RENAMEFOLDER 
TYPE_UPDATEDIR 
TYPE_MAX 

Definition at line 651 of file eventcreate.c.

652{
653 TYPE_None = 0,
654 TYPE_Str,
655// TYPE_U8,
656// TYPE_U16,
657 TYPE_U32,
658};
@ TYPE_Str
Definition: eventcreate.c:654
@ TYPE_U32
Definition: eventcreate.c:657
@ TYPE_None
Definition: eventcreate.c:653

Function Documentation

◆ CheckLogOrSourceExistence()

static BOOL CheckLogOrSourceExistence ( IN LPCWSTR UNCServerName  OPTIONAL,
IN LPCWSTR  EventLogName,
IN LPCWSTR  EventLogSource,
IN BOOL AllowAppSources  OPTIONAL 
)
static

Definition at line 260 of file eventcreate.c.

265{
266 /*
267 * The 'AllowAppSources' parameter allows the usage of
268 * application (non-custom) sources, when set to TRUE.
269 * Its default value is FALSE.
270 */
271
272#define MAX_KEY_LENGTH 255 // or 256 ??
273
275 LONG lRet;
276 HKEY hEventLogKey = NULL, hLogKey = NULL;
277 DWORD NameLen;
278 DWORD dwIndex;
279
280 BOOL LogNameValid, LogSourceValid;
281 BOOL FoundLog = FALSE, FoundSource = FALSE;
282 BOOL SourceAlreadyExists = FALSE, SourceCreated = FALSE, IsCustomSource = FALSE;
283
284 WCHAR LogName[MAX_KEY_LENGTH]; // Current event log being tested for.
285 WCHAR LogNameErr[MAX_KEY_LENGTH]; // Event log in which the source already exists.
286
287 UNREFERENCED_PARAMETER(UNCServerName); // FIXME: Use remote server if needed!
288
289 LogNameValid = (EventLogName && *EventLogName);
290 LogSourceValid = (EventLogSource && *EventLogSource);
291
292 /*
293 * If neither the log name nor the log source are specified,
294 * there is no need to continue. Just fail.
295 */
296 if (!LogNameValid && !LogSourceValid)
297 return FALSE;
298
299 lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, // FIXME: Use remote server if needed!
300 L"SYSTEM\\CurrentControlSet\\Services\\EventLog",
302 &hEventLogKey);
303 if (lRet != ERROR_SUCCESS)
304 goto Quit;
305
306 /*
307 * If we just have a valid log name but no specified source, check whether
308 * the log key exist by atttempting to open it. If we fail: no log.
309 * In all cases we do not perform other tests nor create any source.
310 */
311 if (LogNameValid && !LogSourceValid)
312 {
313 lRet = RegOpenKeyExW(hEventLogKey,
314 EventLogName,
316 &hLogKey);
317 RegCloseKey(hLogKey);
318 FoundLog = (lRet == ERROR_SUCCESS);
319
320 if (FoundLog)
321 {
322 /* Set the flags to consistent values */
323 SourceCreated = TRUE;
324 IsCustomSource = TRUE;
325 }
326 goto Finalize;
327 }
328
329 /* Here, LogSourceValid is always TRUE */
330
331 /*
332 * We now have a valid source and either an event log name or none.
333 * Search for the source existence over all the existing logs:
334 * we loop through the event logs and we will:
335 * - localize whether the specified source exists and in which log it does;
336 * - and at the same time, check whether the specified log does exist.
337 */
338 dwIndex = 0;
339 while (TRUE)
340 {
341 NameLen = ARRAYSIZE(LogName);
342 LogName[0] = L'\0';
343
344 lRet = RegEnumKeyExW(hEventLogKey, dwIndex, LogName, &NameLen,
345 NULL, NULL, NULL, NULL);
346 if (dwIndex > 0)
347 {
348 if (lRet == ERROR_NO_MORE_ITEMS)
349 {
350 /*
351 * We may/may not have found our log and may/may not have found
352 * our source. Quit the loop, we will check those details after.
353 */
354 break; // goto Finalize;
355 }
356 }
357 if (lRet != ERROR_SUCCESS)
358 {
359 /* A registry error happened, just fail */
360 goto Quit;
361 }
362
363 /* We will then continue with the next log */
364 ++dwIndex;
365
366 /* If we have specified a log, check whether we have found it */
367 if (LogNameValid && _wcsicmp(LogName, EventLogName) == 0)
368 {
369 /*
370 * We have found the specified log, but do not break yet: if we have
371 * a specified source, we want to be sure it does not exist elsewhere.
372 */
373 FoundLog = TRUE;
374 }
375
376 /*
377 * The following case: if (LogNameValid && !LogSourceValid) {...}
378 * was already dealt with before. Here, LogSourceValid is always TRUE.
379 */
380
381 /* Now determine whether we need to continue */
382 if (/* LogNameValid && */ FoundLog)
383 {
384#if 0
385 if (!LogSourceValid)
386 {
387 /*
388 * We have found our log and we do not use any source,
389 * we can stop scanning now.
390 */
391 /* Set the flags to consistent values */
392 SourceCreated = TRUE;
393 IsCustomSource = TRUE;
394 break; // goto Finalize;
395 }
396#endif
397 if (SourceAlreadyExists)
398 {
399 /*
400 * We have finally found our log but the source existed elsewhere,
401 * stop scanning and we will error that the source is not in the
402 * expected log. On the contrary, if our log was not found yet,
403 * continue scanning to attempt to find it and, if the log is not
404 * found at the end we will error that the log does not exist.
405 */
406 break; // goto Finalize;
407 }
408 }
409
410 /*
411 * If we have specified a source and have not found it so far,
412 * check for its presence in this log.
413 * NOTE: Here, LogSourceValid is always TRUE.
414 */
415 if (LogSourceValid && !FoundSource)
416 {
417 HKEY hKeySource = NULL;
418
419 /* Check the sources inside this log */
420 lRet = RegOpenKeyExW(hEventLogKey, LogName, 0, KEY_READ, &hLogKey);
421 if (lRet != ERROR_SUCCESS)
422 {
423 /* A registry error happened, just fail */
424 goto Quit;
425 }
426
427 /*
428 * Attempt to open the source key.
429 *
430 * NOTE: Alternatively we could have scanned each source key
431 * in this log by using RegEnumKeyExW.
432 */
433 lRet = RegOpenKeyExW(hLogKey, EventLogSource,
435 &hKeySource);
436
437 /* Get rid of the log key handle */
438 RegCloseKey(hLogKey);
439 hLogKey = NULL;
440
441 if (lRet == ERROR_SUCCESS) // || lRet == ERROR_ACCESS_DENIED
442 {
443 /*
444 * We have found our source in this log (it can be
445 * in a different log than the one specified).
446 */
447 FoundSource = TRUE;
448 // lRet = ERROR_SUCCESS;
449 }
450 else if (lRet == ERROR_FILE_NOT_FOUND)
451 {
452 /* Our source was not found there */
453 lRet = ERROR_SUCCESS;
454 hKeySource = NULL;
455 }
456 else // if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
457 {
458 /* A registry error happened, but we continue scanning the other logs... */
459 hKeySource = NULL;
460 }
461
462 /* If we have not found our source, continue scanning the other logs */
463 if (!FoundSource)
464 continue;
465
466 /*
467 * We have found our source, but is it in the correct log?
468 *
469 * NOTE: We check only in the case we have specified a log,
470 * otherwise we just care about the existence of the source
471 * and we do not check for its presence in the other logs.
472 */
473 if (LogNameValid && !(FoundLog && _wcsicmp(LogName, EventLogName) == 0))
474 {
475 /* Now get rid of the source key handle */
476 RegCloseKey(hKeySource);
477 hKeySource = NULL;
478
479 /* The source is in another log than the specified one */
480 SourceAlreadyExists = TRUE;
481
482 /* Save the log name in which the source already exists */
483 RtlCopyMemory(LogNameErr, LogName, sizeof(LogName));
484
485 /*
486 * We continue because we want to also know whether we can
487 * still find our specified log (and we will error that the
488 * source exists elsewhere), or whether the log does not exist
489 * (and we will error accordingly).
490 */
491 continue;
492 }
493
494 /*
495 * We have found our source, and if we have specified a log,
496 * the source is in the correct log.
497 */
498 SourceCreated = TRUE;
499
500 /*
501 * Check whether this is one of our custom sources
502 * (application sources do not have this value present).
503 */
504 IsCustomSource = FALSE;
505
506 lRet = RegQueryValueExW(hKeySource, L"CustomSource", NULL, NULL, NULL, NULL);
507
508 /* Now get rid of the source key handle */
509 RegCloseKey(hKeySource);
510 hKeySource = NULL;
511
512 if (lRet == ERROR_SUCCESS)
513 {
514 IsCustomSource = TRUE;
515 }
516 else if (lRet == ERROR_FILE_NOT_FOUND)
517 {
518 // IsCustomSource = FALSE;
519 }
520 else // if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
521 {
522 /* A registry error happened, just fail */
523 goto Quit;
524 }
525
526 /*
527 * We have found our source and it may be (or not) a custom source,
528 * and it is in the correct event log (if we have specified one).
529 * Break the search loop.
530 */
531 break; // goto Finalize;
532 }
533 }
534
535 /*
536 * No errors happened so far.
537 * Perform last validity checks (the flags are all valid and 'LogName'
538 * contains the name of the last log having been tested for).
539 */
541 lRet = ERROR_SUCCESS; // but do not set Success to TRUE yet.
542
543 // FIXME: Shut up a GCC warning/error about 'SourceCreated' being unused.
544 // We will use it later on.
545 UNREFERENCED_PARAMETER(SourceCreated);
546
547 /*
548 * The source does not exist (SourceCreated == FALSE), create it.
549 * Note that we then must have a specified log that exists on the system.
550 */
551 // NOTE: IsCustomSource always FALSE here.
552
553 if (LogNameValid && !FoundLog)
554 {
555 /* We have specified a log but it does not exist! */
556 ConResPrintf(StdErr, IDS_LOG_NOT_FOUND, EventLogName);
557 goto Quit;
558 }
559
560 //
561 // Here, LogNameValid == TRUE && FoundLog == TRUE, or
562 // LogNameValid == FALSE && FoundLog == FALSE.
563 //
564
565 if (LogNameValid /* && FoundLog */ && !LogSourceValid /* && !FoundSource && !SourceAlreadyExists */)
566 {
567 /* No source, just use the log */
568 // NOTE: For this case, SourceCreated and IsCustomSource were both set to TRUE.
569 Success = TRUE;
570 goto Quit;
571 }
572
573 if (/* LogSourceValid && */ FoundSource && SourceAlreadyExists)
574 {
575 /* The source is in another log than the specified one */
577 goto Quit;
578 }
579
580 if (/* LogSourceValid && */ FoundSource && !SourceAlreadyExists)
581 {
582 /* We can directly use the source */
583
584 // if (SourceCreated)
585 {
586 /* The source already exists, check whether this is a custom one */
587 if (IsCustomSource || AllowAppSources)
588 {
589 /* This is a custom source, fine! */
590 Success = TRUE;
591 goto Quit;
592 }
593 else
594 {
595 /* This is NOT a custom source, we must return an error! */
597 goto Quit;
598 }
599 }
600 }
601
602 if (LogSourceValid && !FoundSource)
603 {
604 if (!LogNameValid /* && !FoundLog */)
605 {
606 /* The log name is not specified, we cannot create the source */
608 goto Quit;
609 }
610 else // LogNameValid && FoundLog
611 {
612 /* Create a new source in the specified log */
613
614 lRet = RegOpenKeyExW(hEventLogKey,
615 EventLogName,
616 0, KEY_CREATE_SUB_KEY, // KEY_WRITE
617 &hLogKey);
618 if (lRet != ERROR_SUCCESS)
619 goto Quit;
620
621 /* Register the new event source */
622 lRet = InstallEventSource(hLogKey, EventLogSource);
623
624 RegCloseKey(hLogKey);
625
626 if (lRet != ERROR_SUCCESS)
627 {
628 PrintError(lRet);
629 ConPrintf(StdErr, L"Impossible to create the source `%s' for log `%s'!\n",
630 EventLogSource, EventLogName);
631 goto Quit;
632 }
633
634 SourceCreated = TRUE;
635 Success = TRUE;
636 }
637 }
638
639Quit:
640 if (hEventLogKey)
641 RegCloseKey(hEventLogKey);
642
643 SetLastError(lRet);
644
645 return Success;
646}
#define IDS_SOURCE_NOCREATE
Definition: resource.h:16
#define IDS_LOG_NOT_FOUND
Definition: resource.h:15
#define IDS_SOURCE_NOT_CUSTOM
Definition: resource.h:18
#define IDS_SOURCE_EXISTS
Definition: resource.h:17
void ConPrintf(FILE *fp, LPCWSTR psz,...)
Definition: fc.c:20
void ConResPrintf(FILE *fp, UINT nID,...)
Definition: fc.c:33
#define StdErr
Definition: fc.c:15
void ConResPuts(FILE *fp, UINT nID)
Definition: fc.c:27
static FCRET Finalize(FILECOMPARE *pFC, struct list *ptr0, struct list *ptr1, BOOL fDifferent)
Definition: text.h:515
PEVENTSOURCE EventLogSource
Definition: eventlog.c:35
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2533
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4132
#define SetLastError(x)
Definition: compat.h:752
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
VOID PrintError(DWORD dwError)
Definition: eventcreate.c:111
#define MAX_KEY_LENGTH
static LONG InstallEventSource(IN HKEY hEventLogKey, IN LPCWSTR EventLogSource)
Definition: eventcreate.c:178
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by wmain().

◆ DoParse()

BOOL DoParse ( IN INT  argc,
IN WCHAR argv[],
IN OUT POPTION  Options,
IN ULONG  NumOptions,
IN PRINT_ERROR_FUNC PrintErrorFunc  OPTIONAL 
)

FIXME: This test is problematic if this concerns the last option in the command-line! A hack-fix is to repeat this check after the 'for'-loop.

HACK-fix for the check done inside the 'for'-loop.

Definition at line 726 of file eventcreate.c.

732{
733 BOOL ExclusiveOptionPresent = FALSE;
734 PWSTR OptionStr = NULL;
735 UINT i;
736
737 /*
738 * The 'Option' index is reset to 'NumOptions' (total number of elements in
739 * the 'Options' list) before retrieving a new option. This is done so that
740 * we know it cannot index a valid option at that moment.
741 */
742 UINT Option = NumOptions;
743
744 /* Parse command line for options */
745 for (i = 1; i < argc; ++i)
746 {
747 /* Check for new options */
748
749 if (argv[i][0] == L'-' || argv[i][0] == L'/')
750 {
753 if (Option != NumOptions)
754 {
755 if (PrintErrorFunc)
756 PrintErrorFunc(ValueRequired, OptionStr);
757 return FALSE;
758 }
759
760 /*
761 * If we have already encountered an (unique) exclusive option,
762 * just break now.
763 */
764 if (ExclusiveOptionPresent)
765 break;
766
767 OptionStr = argv[i];
768
769 /* Lookup for the option in the list of options */
770 for (Option = 0; Option < NumOptions; ++Option)
771 {
772 if (_wcsicmp(OptionStr + 1, Options[Option].OptionName) == 0)
773 break;
774 }
775
776 if (Option >= NumOptions)
777 {
778 if (PrintErrorFunc)
779 PrintErrorFunc(InvalidOption, OptionStr);
780 return FALSE;
781 }
782
783
784 /* An option is being set */
785
786 if (Options[Option].MaxOfInstances != 0 &&
787 Options[Option].Instances >= Options[Option].MaxOfInstances)
788 {
789 if (PrintErrorFunc)
790 PrintErrorFunc(TooManySameOption, OptionStr, Options[Option].MaxOfInstances);
791 return FALSE;
792 }
793 ++Options[Option].Instances;
794
795 Options[Option].OptionStr = OptionStr;
796
797 /*
798 * If this option is exclusive, remember it for later.
799 * We will then short-circuit the regular validity checks
800 * and instead check whether this is the only option specified
801 * on the command-line.
802 */
803 if (Options[Option].Flags & OPTION_EXCLUSIVE)
804 ExclusiveOptionPresent = TRUE;
805
806 /* Preprocess the option before setting its value */
807 switch (Options[Option].Type)
808 {
809 case TYPE_None: // ~= TYPE_Bool
810 {
811 /* Set the associated boolean */
812 BOOL* pBool = (BOOL*)Options[Option].Value;
813 *pBool = TRUE;
814
815 /* No associated value, so reset the index */
816 Option = NumOptions;
817 }
818
819 /* Fall-back */
820
821 case TYPE_Str:
822
823 // case TYPE_U8:
824 // case TYPE_U16:
825 case TYPE_U32:
826 break;
827
828 default:
829 {
830 wprintf(L"PARSER: Unsupported option type %lu\n", Options[Option].Type);
831 break;
832 }
833 }
834 }
835 else
836 {
837 /* A value for an option is being set */
838 switch (Options[Option].Type)
839 {
840 case TYPE_None:
841 {
842 /* There must be no associated value */
843 if (PrintErrorFunc)
844 PrintErrorFunc(ValueNotAllowed, OptionStr);
845 return FALSE;
846 }
847
848 case TYPE_Str:
849 {
850 /* Retrieve the string */
851 PWSTR* pStr = (PWSTR*)Options[Option].Value;
852 *pStr = argv[i];
853
854 /* Trim whitespace if needed */
855 if (Options[Option].Flags & OPTION_TRIM_SPACE)
856 *pStr = TrimLeftRightWhitespace(*pStr);
857
858 /* Check whether or not the value can be empty */
859 if ((Options[Option].Flags & OPTION_NOT_EMPTY) && !**pStr)
860 {
861 /* Value cannot be empty */
862 if (PrintErrorFunc)
863 PrintErrorFunc(ValueIsEmpty, OptionStr);
864 return FALSE;
865 }
866
867 /* Check whether the value is part of the allowed list of values */
868 if (Options[Option].Flags & OPTION_ALLOWED_LIST)
869 {
870 PWSTR AllowedValues, Scan;
872
873 AllowedValues = Options[Option].AllowedValues;
874 if (!AllowedValues)
875 {
876 /* The array is empty, no allowed values */
877 if (PrintErrorFunc)
878 PrintErrorFunc(InvalidValue, *pStr, OptionStr);
879 return FALSE;
880 }
881
882 Scan = AllowedValues;
883 while (*Scan)
884 {
885 /* Find the values separator */
886 Length = wcscspn(Scan, L"|");
887
888 /* Check whether this is an allowed value */
889 if ((wcslen(*pStr) == Length) &&
890 (_wcsnicmp(*pStr, Scan, Length) == 0))
891 {
892 /* Found it! */
893 break;
894 }
895
896 /* Go to the next test value */
897 Scan += Length;
898 if (*Scan) ++Scan; // Skip the separator
899 }
900
901 if (!*Scan)
902 {
903 /* The value is not allowed */
904 if (PrintErrorFunc)
905 PrintErrorFunc(InvalidValue, *pStr, OptionStr);
906 return FALSE;
907 }
908 }
909
910 break;
911 }
912
913 // case TYPE_U8:
914 // case TYPE_U16:
915 case TYPE_U32:
916 {
917 PWCHAR pszNext = NULL;
918
919 /* The number is specified in base 10 */
920 // NOTE: We might use '0' so that the base is automatically determined.
921 *(ULONG*)Options[Option].Value = wcstoul(argv[i], &pszNext, 10);
922 if (*pszNext)
923 {
924 /* The value is not a valid numeric value and is not allowed */
925 if (PrintErrorFunc)
926 PrintErrorFunc(InvalidValue, argv[i], OptionStr);
927 return FALSE;
928 }
929 break;
930 }
931
932 default:
933 {
934 wprintf(L"PARSER: Unsupported option type %lu\n", Options[Option].Type);
935 break;
936 }
937 }
938
939 /* Reset the index */
940 Option = NumOptions;
941 }
942 }
943
945 if (Option != NumOptions)
946 {
947 if (PrintErrorFunc)
948 PrintErrorFunc(ValueRequired, OptionStr);
949 return FALSE;
950 }
951
952 /* Finalize options validity checks */
953
954 if (ExclusiveOptionPresent)
955 {
956 /*
957 * An exclusive option present on the command-line:
958 * check whether this is the only option specified.
959 */
960 for (i = 0; i < NumOptions; ++i)
961 {
962 if (!(Options[i].Flags & OPTION_EXCLUSIVE) && (Options[i].Instances != 0))
963 {
964 /* A non-exclusive option is present on the command-line, fail */
965 if (PrintErrorFunc)
966 PrintErrorFunc(InvalidSyntax);
967 return FALSE;
968 }
969 }
970
971 /* No other checks needed, we are done */
972 return TRUE;
973 }
974
975 /* Check whether the required options were specified */
976 for (i = 0; i < NumOptions; ++i)
977 {
978 /* Regular validity checks */
979 if ((Options[i].Flags & OPTION_MANDATORY) && (Options[i].Instances == 0))
980 {
981 if (PrintErrorFunc)
982 PrintErrorFunc(MandatoryOptionAbsent, Options[i].OptionName);
983 return FALSE;
984 }
985 }
986
987 /* All checks are done */
988 return TRUE;
989}
static int argc
Definition: ServiceArgs.c:12
Type
Definition: Type.h:7
#define OPTION_NOT_EMPTY
Definition: eventcreate.c:661
#define OPTION_EXCLUSIVE
Definition: eventcreate.c:663
#define OPTION_ALLOWED_LIST
Definition: eventcreate.c:660
static PWSTR TrimLeftRightWhitespace(IN PWSTR String)
Definition: eventcreate.c:691
#define OPTION_TRIM_SPACE
Definition: eventcreate.c:662
#define OPTION_MANDATORY
Definition: eventcreate.c:664
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define argv
Definition: mplay32.c:18
unsigned int UINT
Definition: ndis.h:50
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_Check_return_ _CRTIMP size_t __cdecl wcscspn(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
uint16_t * PWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define wprintf(...)
Definition: whoami.c:18
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by wmain().

◆ GetUserToken()

static BOOL GetUserToken ( OUT PTOKEN_USER ppUserToken)
static

Definition at line 123 of file eventcreate.c.

125{
127 DWORD dwError;
128 HANDLE hToken;
129 DWORD cbTokenBuffer = 0;
130 PTOKEN_USER pUserToken = NULL;
131
132 *ppUserToken = NULL;
133
134 /* Get the process token */
136 return FALSE;
137
138 /* Retrieve token's information */
139 if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &cbTokenBuffer))
140 {
141 dwError = GetLastError();
142 if (dwError != ERROR_INSUFFICIENT_BUFFER)
143 goto Quit;
144 }
145
146 pUserToken = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbTokenBuffer);
147 if (!pUserToken)
148 {
149 dwError = ERROR_NOT_ENOUGH_MEMORY;
150 goto Quit;
151 }
152
153 if (!GetTokenInformation(hToken, TokenUser, pUserToken, cbTokenBuffer, &cbTokenBuffer))
154 {
155 dwError = GetLastError();
156 goto Quit;
157 }
158
159 Success = TRUE;
160 dwError = ERROR_SUCCESS;
161 *ppUserToken = pUserToken;
162
163Quit:
164 if (Success == FALSE)
165 {
166 if (pUserToken)
167 HeapFree(GetProcessHeap(), 0, pUserToken);
168 }
169
170 CloseHandle(hToken);
171
172 SetLastError(dwError);
173
174 return Success;
175}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define GetCurrentProcess()
Definition: compat.h:759
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966

Referenced by wmain().

◆ InstallEventSource()

static LONG InstallEventSource ( IN HKEY  hEventLogKey,
IN LPCWSTR  EventLogSource 
)
static

Definition at line 178 of file eventcreate.c.

181{
182 LONG lRet;
183 HKEY hSourceKey = NULL;
184 DWORD dwDisposition = 0;
186
187 LPCWSTR EventMessageFile;
188 DWORD PathSize;
189 WCHAR ExePath[MAX_PATH];
190
191 lRet = RegCreateKeyExW(hEventLogKey,
195 &hSourceKey, &dwDisposition);
196 if (lRet != ERROR_SUCCESS)
197 goto Quit;
198 if (dwDisposition != REG_CREATED_NEW_KEY)
199 {
200 /* The source key already exists, just quit */
201 goto Quit;
202 }
203
204 /* We just have created the new source. Add the values. */
205
206 /*
207 * Retrieve the full path of the current running executable.
208 * We need it to install our custom event source.
209 * - In case of success, try to replace the ReactOS installation path
210 * (if present in the executable path) by %SystemRoot%.
211 * - In case of failure, use a default path.
212 */
213 PathSize = GetModuleFileNameW(NULL, ExePath, ARRAYSIZE(ExePath));
214 if ((PathSize == 0) || (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
215 {
216 /* We failed, copy the default value */
217 StringCchCopyW(ExePath, ARRAYSIZE(ExePath),
218 L"%SystemRoot%\\System32\\" APPLICATION_NAME L".exe");
219 }
220 else
221 {
222 /* Alternatively one can use SharedUserData->NtSystemRoot */
223 WCHAR TmpDir[ARRAYSIZE(ExePath)];
224 PathSize = GetSystemWindowsDirectoryW(TmpDir, ARRAYSIZE(TmpDir));
225 if ((PathSize > 0) && (_wcsnicmp(ExePath, TmpDir, PathSize) == 0))
226 {
227 StringCchCopyW(TmpDir, ARRAYSIZE(TmpDir), L"%SystemRoot%");
228 StringCchCatW(TmpDir, ARRAYSIZE(TmpDir), ExePath + PathSize);
229 StringCchCopyW(ExePath, ARRAYSIZE(ExePath), TmpDir);
230 }
231 }
232 EventMessageFile = ExePath;
233
234 lRet = ERROR_SUCCESS;
235
236 dwData = 1;
237 RegSetValueExW(hSourceKey, L"CustomSource", 0, REG_DWORD,
238 (LPBYTE)&dwData, sizeof(dwData));
239
240 // FIXME: Set those flags according to caller's rights?
241 // Or, if we are using the Security log?
243 /* | EVENTLOG_AUDIT_SUCCESS | EVENTLOG_AUDIT_FAILURE */ ;
244 RegSetValueExW(hSourceKey, L"TypesSupported", 0, REG_DWORD,
245 (LPBYTE)&dwData, sizeof(dwData));
246
247 RegSetValueExW(hSourceKey, L"EventMessageFile", 0, REG_EXPAND_SZ,
248 (LPBYTE)EventMessageFile, (wcslen(EventMessageFile) + 1) * sizeof(WCHAR));
249
250 RegFlushKey(hSourceKey);
251
252Quit:
253 if (hSourceKey)
254 RegCloseKey(hSourceKey);
255
256 return lRet;
257}
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2980
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4911
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2397
#define APPLICATION_NAME
Definition: eventcreate.c:108
static HANDLE ULONG_PTR dwData
Definition: file.c:35
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define REG_DWORD
Definition: sdbapi.c:596
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
unsigned char * LPBYTE
Definition: typedefs.h:53
#define EVENTLOG_ERROR_TYPE
Definition: winnt_old.h:2834
#define EVENTLOG_INFORMATION_TYPE
Definition: winnt_old.h:2836
#define EVENTLOG_SUCCESS
Definition: winnt_old.h:2833
#define EVENTLOG_WARNING_TYPE
Definition: winnt_old.h:2835
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by CheckLogOrSourceExistence().

◆ PrintError()

VOID PrintError ( DWORD  dwError)

Definition at line 111 of file eventcreate.c.

112{
113 if (dwError == ERROR_SUCCESS)
114 return;
115
117 NULL, dwError, LANG_USER_DEFAULT);
118 ConPuts(StdErr, L"\n");
119}
void ConPuts(FILE *fp, LPCWSTR psz)
Definition: fc.c:16
INT ConMsgPuts(IN PCON_STREAM Stream, IN DWORD dwFlags, IN LPCVOID lpSource OPTIONAL, IN DWORD dwMessageId, IN DWORD dwLanguageId)
Definition: outstream.c:837
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423

Referenced by CheckLogOrSourceExistence(), and wmain().

◆ PrintParserError()

static VOID __cdecl PrintParserError ( PARSER_ERROR  Error,
  ... 
)
static

Definition at line 996 of file eventcreate.c.

997{
998 /* WARNING: Please keep this lookup table in sync with the resources! */
999 static UINT ErrorIDs[] =
1000 {
1001 0, /* Success */
1002 IDS_BADSYNTAX_0, /* InvalidSyntax */
1003 IDS_INVALIDSWITCH, /* InvalidOption */
1004 IDS_BADSYNTAX_1, /* ValueRequired */
1005 IDS_BADSYNTAX_2, /* ValueIsEmpty */
1006 IDS_BADSYNTAX_3, /* InvalidValue */
1007 IDS_BADSYNTAX_4, /* ValueNotAllowed */
1008 IDS_BADSYNTAX_5, /* TooManySameOption */
1009 IDS_BADSYNTAX_6, /* MandatoryOptionAbsent */
1010 };
1011
1012 va_list args;
1013
1014 if (Error < ARRAYSIZE(ErrorIDs))
1015 {
1017 ConResPrintfV(StdErr, ErrorIDs[Error], args);
1018 va_end(args);
1019
1020 if (Error != Success)
1022 }
1023 else
1024 {
1025 ConPrintf(StdErr, L"PARSER: Unknown error %d\n", Error);
1026 }
1027}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define IDS_USAGE
Definition: resource.h:3
#define IDS_INVALIDSWITCH
Definition: resource.h:4
#define IDS_BADSYNTAX_1
Definition: resource.h:7
#define IDS_BADSYNTAX_6
Definition: resource.h:12
#define IDS_BADSYNTAX_2
Definition: resource.h:8
#define IDS_BADSYNTAX_3
Definition: resource.h:9
#define IDS_BADSYNTAX_0
Definition: resource.h:6
#define IDS_BADSYNTAX_4
Definition: resource.h:10
#define IDS_BADSYNTAX_5
Definition: resource.h:11
BOOL Error
Definition: chkdsk.c:66
INT ConResPrintfV(IN PCON_STREAM Stream, IN UINT uID, IN va_list args)
Definition: outstream.c:695
#define args
Definition: format.c:66
Definition: match.c:390

Referenced by wmain().

◆ TrimLeftRightWhitespace()

static PWSTR TrimLeftRightWhitespace ( IN PWSTR  String)
static

Definition at line 691 of file eventcreate.c.

693{
694 PWSTR pStr;
695
696 /* Trim whitespace on left (just advance the pointer) */
697 while (*String && iswspace(*String))
698 ++String;
699
700 /* Trim whitespace on right (NULL-terminate) */
701 pStr = String + wcslen(String) - 1;
702 while (pStr >= String && iswspace(*pStr))
703 --pStr;
704 *++pStr = L'\0';
705
706 /* Return the modified pointer */
707 return String;
708}
#define iswspace(_c)
Definition: ctype.h:669
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

Referenced by DoParse().

◆ wmain()

int wmain ( int  argc,
WCHAR argv[] 
)

Definition at line 1029 of file eventcreate.c.

1030{
1031 BOOL Success = FALSE;
1032 HANDLE hEventLog;
1033 PTOKEN_USER pUserToken;
1034
1035 /* Default option values */
1036 BOOL bDisplayHelp = FALSE;
1037 PWSTR szSystem = NULL;
1038 PWSTR szDomainUser = NULL;
1039 PWSTR szPassword = NULL;
1040 PWSTR szLogName = NULL;
1041 PWSTR szEventSource = NULL;
1042 PWSTR szEventType = NULL;
1044 ULONG ulEventType = EVENTLOG_INFORMATION_TYPE;
1045 ULONG ulEventCategory = 0;
1046 ULONG ulEventIdentifier = 0;
1047
1048 OPTION Options[] =
1049 {
1050 /* Help */
1051 NEW_OPT(L"?", TYPE_None, // ~= TYPE_Bool,
1053 1,
1054 sizeof(bDisplayHelp), &bDisplayHelp),
1055
1056 /* System */
1057 NEW_OPT(L"S", TYPE_Str,
1059 1,
1060 sizeof(szSystem), &szSystem),
1061
1062 /* Domain & User */
1063 NEW_OPT(L"U", TYPE_Str,
1065 1,
1066 sizeof(szDomainUser), &szDomainUser),
1067
1068 /* Password */
1069 NEW_OPT(L"P", TYPE_Str,
1070 0,
1071 1,
1072 sizeof(szPassword), &szPassword),
1073
1074 /* Log name */
1075 NEW_OPT(L"L", TYPE_Str,
1077 1,
1078 sizeof(szLogName), &szLogName),
1079
1080 /* Event source */
1081 NEW_OPT(L"SO", TYPE_Str,
1083 1,
1084 sizeof(szEventSource), &szEventSource),
1085
1086 /* Event type */
1087 NEW_OPT_EX(L"T", TYPE_Str,
1089 L"SUCCESS|ERROR|WARNING|INFORMATION",
1090 1,
1091 sizeof(szEventType), &szEventType),
1092
1093 /* Event category (ReactOS additional option) */
1094 NEW_OPT(L"C", TYPE_U32,
1095 0,
1096 1,
1097 sizeof(ulEventCategory), &ulEventCategory),
1098
1099 /* Event ID */
1100 NEW_OPT(L"ID", TYPE_U32,
1102 1,
1103 sizeof(ulEventIdentifier), &ulEventIdentifier),
1104
1105 /* Event description */
1106 NEW_OPT(L"D", TYPE_Str,
1108 1,
1109 sizeof(szDescription), &szDescription),
1110 };
1111#define OPT_SYSTEM (Options[1])
1112#define OPT_USER (Options[2])
1113#define OPT_PASSWD (Options[3])
1114#define OPT_EVTID (Options[8])
1115
1116 /* Initialize the Console Standard Streams */
1118
1119 /* Parse command line for options */
1121 return EXIT_FAILURE;
1122
1123 /* Finalize options validity checks */
1124
1125 if (bDisplayHelp)
1126 {
1127 if (argc > 2)
1128 {
1129 /* Invalid syntax */
1131 return EXIT_FAILURE;
1132 }
1133
1135 return EXIT_SUCCESS;
1136 }
1137
1138 if (szSystem || szDomainUser || szPassword)
1139 {
1140 // TODO: Implement!
1141 if (szSystem)
1143 if (szDomainUser)
1145 if (szPassword)
1147 return EXIT_FAILURE;
1148 }
1149
1150 if (ulEventIdentifier < EVENT_ID_MIN || ulEventIdentifier > EVENT_ID_MAX)
1151 {
1152 /* Invalid event identifier */
1155 return EXIT_FAILURE;
1156 }
1157
1158 /*
1159 * Set the event type. Note that we forbid the user
1160 * to use security auditing types.
1161 */
1162 if (_wcsicmp(szEventType, L"SUCCESS") == 0)
1163 ulEventType = EVENTLOG_SUCCESS;
1164 else
1165 if (_wcsicmp(szEventType, L"ERROR") == 0)
1166 ulEventType = EVENTLOG_ERROR_TYPE;
1167 else
1168 if (_wcsicmp(szEventType, L"WARNING") == 0)
1169 ulEventType = EVENTLOG_WARNING_TYPE;
1170 else
1171 if (_wcsicmp(szEventType, L"INFORMATION") == 0)
1172 ulEventType = EVENTLOG_INFORMATION_TYPE;
1173 else
1174 {
1175 /* Use a default event type */
1176 ulEventType = EVENTLOG_SUCCESS;
1177 }
1178
1179 /*
1180 * If we have a source, do not care about the log (as long as we will be
1181 * able to find the source later).
1182 * But if we do not have a source, then two cases:
1183 * - either we have a log name so that we will use OpenEventLog (and use
1184 * default log's source), unless this is the Application log in which case
1185 * we use the default source;
1186 * - or we do not have a log name so that we use default log and source names.
1187 */
1188 if (!szEventSource)
1189 {
1190 if (!szLogName)
1191 szLogName = L"Application";
1192
1193 if (_wcsicmp(szLogName, L"Application") == 0)
1194 szEventSource = APPLICATION_NAME;
1195 }
1196
1197 // FIXME: Check whether szLogName == L"Security" !!
1198
1199 /*
1200 * The event APIs OpenEventLog and RegisterEventSource fall back to using
1201 * the 'Application' log when the specified log name or event source do not
1202 * exist on the system.
1203 * To prevent that and be able to error the user that the specified log name
1204 * or event source do not exist, we need to manually perform the existence
1205 * checks by ourselves.
1206 *
1207 * Check whether either the specified event log OR event source exist on
1208 * the system. If the event log does not exist, return an error. Otherwise
1209 * check whether a specified source already exists (everywhere). If found
1210 * in a different log, return an error. If not found, create the source
1211 * in the specified event log.
1212 *
1213 * NOTE: By default we forbid the usage of application (non-custom) sources.
1214 * An optional switch can be added to EventCreate to allow such sources
1215 * to be used.
1216 */
1217 if (!CheckLogOrSourceExistence(szSystem, szLogName, szEventSource, FALSE))
1218 {
1220 return EXIT_FAILURE;
1221 }
1222
1223 /* Open the event log, by source or by log name */
1224 if (szEventSource) // && *szEventSource
1225 hEventLog = RegisterEventSourceW(szSystem, szEventSource);
1226 else
1227 hEventLog = OpenEventLogW(szSystem, szLogName);
1228
1229 if (!hEventLog)
1230 {
1232 return EXIT_FAILURE;
1233 }
1234
1235 /* Retrieve the current user token and report the event */
1236 if (GetUserToken(&pUserToken))
1237 {
1238 Success = ReportEventW(hEventLog,
1239 ulEventType,
1240 ulEventCategory,
1241 ulEventIdentifier,
1242 pUserToken->User.Sid,
1243 1, // One string
1244 0, // No raw data
1246 NULL // No raw data
1247 );
1248 if (!Success)
1249 {
1251 ConPuts(StdErr, L"Failed to report event!\n");
1252 }
1253 else
1254 {
1255 /* Show success */
1256 ConPuts(StdOut, L"\n");
1257 if (!szEventSource)
1258 ConResPrintf(StdOut, IDS_SUCCESS_1, szEventType, szLogName);
1259 else if (!szLogName)
1260 ConResPrintf(StdOut, IDS_SUCCESS_2, szEventType, szEventSource);
1261 else
1262 ConResPrintf(StdOut, IDS_SUCCESS_3, szEventType, szLogName, szEventSource);
1263 }
1264
1265 HeapFree(GetProcessHeap(), 0, pUserToken);
1266 }
1267 else
1268 {
1270 ConPuts(StdErr, L"GetUserToken() failed!\n");
1271 }
1272
1273 /* Close the event log */
1274 if (szEventSource && *szEventSource)
1275 DeregisterEventSource(hEventLog);
1276 else
1277 CloseEventLog(hEventLog);
1278
1279 return (Success ? EXIT_SUCCESS : EXIT_FAILURE);
1280}
#define IDS_HELP
Definition: resource.h:3
#define IDS_SUCCESS_2
Definition: resource.h:21
#define IDS_SUCCESS_3
Definition: resource.h:22
#define IDS_BADSYNTAX_7
Definition: resource.h:13
#define IDS_SWITCH_UNIMPLEMENTED
Definition: resource.h:24
#define IDS_SUCCESS_1
Definition: resource.h:20
#define ConInitStdStreams()
Definition: fc.c:13
#define StdOut
Definition: fc.c:14
static const WCHAR szDescription[]
Definition: provider.c:55
HANDLE WINAPI OpenEventLogW(IN LPCWSTR lpUNCServerName, IN LPCWSTR lpSourceName)
Definition: eventlog.c:985
BOOL WINAPI CloseEventLog(IN HANDLE hEventLog)
Definition: eventlog.c:427
BOOL WINAPI ReportEventW(IN HANDLE hEventLog, IN WORD wType, IN WORD wCategory, IN DWORD dwEventID, IN PSID lpUserSid, IN WORD wNumStrings, IN DWORD dwDataSize, IN LPCWSTR *lpStrings, IN LPVOID lpRawData)
Definition: eventlog.c:1516
BOOL WINAPI DeregisterEventSource(IN HANDLE hEventLog)
Definition: eventlog.c:473
HANDLE WINAPI RegisterEventSourceW(IN LPCWSTR lpUNCServerName, IN LPCWSTR lpSourceName)
Definition: eventlog.c:1295
BOOL DoParse(IN INT argc, IN WCHAR *argv[], IN OUT POPTION Options, IN ULONG NumOptions, IN PRINT_ERROR_FUNC PrintErrorFunc OPTIONAL)
Definition: eventcreate.c:726
#define OPT_USER
#define OPT_SYSTEM
static BOOL GetUserToken(OUT PTOKEN_USER *ppUserToken)
Definition: eventcreate.c:123
static VOID __cdecl PrintParserError(PARSER_ERROR Error,...)
Definition: eventcreate.c:996
#define OPT_PASSWD
static BOOL CheckLogOrSourceExistence(IN LPCWSTR UNCServerName OPTIONAL, IN LPCWSTR EventLogName, IN LPCWSTR EventLogSource, IN BOOL AllowAppSources OPTIONAL)
Definition: eventcreate.c:260
#define EVENT_ID_MIN
Definition: eventcreate.c:101
#define EVENT_ID_MAX
Definition: eventcreate.c:102
#define NEW_OPT(Name, Type, Flags, MaxOfInstances, ValueSize, ValueBuffer)
Definition: eventcreate.c:684
#define OPT_EVTID
#define NEW_OPT_EX(Name, Type, Flags, AllowedValues, MaxOfInstances, ValueSize, ValueBuffer)
Definition: eventcreate.c:687
#define EXIT_FAILURE
Definition: jerror.c:33
#define EXIT_SUCCESS
Definition: rdjpgcom.c:55
SID_AND_ATTRIBUTES User
Definition: setypes.h:1010