もののついで

動作は結構怪しいが。
[eventcreateex.c]


#include <stdio.h>
#include <windows.h>

char* op_L = NULL;
char* op_T = NULL;
char* op_SO = NULL;
char* op_C = NULL;
char* op_ID = NULL;
char* op_D = NULL;

HKEY regkey = NULL;

void set_op(char** op, char* str) {
*op = malloc(strlen(str)+1);
strcpy(*op, str);
}

void set_registry() {
DWORD type;
DWORD value = 1;
char keyname[8192];
strcpy(keyname, "SYSTEM\\CurrentControlSet\\Services\\Eventlog\\");
strcat(keyname, op_L);
strcat(keyname, "\\");
strcat(keyname, op_SO);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_ALL_ACCESS, &regkey) != ERROR_SUCCESS) {
printf("%s?\n", op_SO);
exit(1);
}
if (RegQueryValueEx(regkey, "CustomSource", NULL, &type, NULL, NULL) != ERROR_SUCCESS) {
RegSetValueEx(regkey, "CustomSource", 0, REG_DWORD, &value, sizeof(DWORD));
} else {
RegCloseKey(regkey);
regkey = NULL;
}
}

void report_event() {
HANDLE evtlog;
WORD type;
WORD category;
DWORD id;
LPCTSTR strs[1];

unsigned int t;
int i;

if (op_C != NULL) {
sscanf(op_C, "%u", &t);
category = (WORD)t;
} else {
category = 0;
}

sscanf(op_ID, "%u", &t);
id = (DWORD)t;

for (i = 0; i < strlen(op_T); i++) op_T[i] = toupper(op_T[i]);
if (strcmp(op_T, "ERROR") == 0) type = EVENTLOG_ERROR_TYPE;
else if (strcmp(op_T, "WARNING") == 0) type = EVENTLOG_WARNING_TYPE;
else if (strcmp(op_T, "INFORMATION") == 0) type = EVENTLOG_INFORMATION_TYPE;
else if (strcmp(op_T, "SUCCESS") == 0) type = EVENTLOG_AUDIT_SUCCESS;
else if (strcmp(op_T, "FAILURE") == 0) type = EVENTLOG_AUDIT_FAILURE;
else {
printf("bad /T.\n");
return;
}

strs[0] = (LPCTSTR)op_D;

evtlog = RegisterEventSource(NULL, op_SO);
if (ReportEvent(evtlog, type, category, id, NULL, 1, 0, strs, NULL) == 0) {
printf("cann't report.\n");
}
DeregisterEventSource(evtlog);
}

void unset_registry() {
if (regkey != NULL) {
RegDeleteValue(regkey, "CustomSource");
RegCloseKey(regkey);
}
}

int main(int argc, char* argv[]) {
int i, j;

for (i = 1; i < argc; i++) {
if (argv[i][0] == '/') {
char op[5];
strncpy(op, argv[i], sizeof(op));
if (i+1 < argc && argv[i+1][0] != '/') {
for (j = 0; j < strlen(op); j++) op[j] = toupper(op[j]);
if (strcmp(op, "/L") == 0) set_op(&op_L, argv[i+1]);
if (strcmp(op, "/T") == 0) set_op(&op_T, argv[i+1]);
if (strcmp(op, "/SO") == 0) set_op(&op_SO, argv[i+1]);
if (strcmp(op, "/C") == 0) set_op(&op_C, argv[i+1]);
if (strcmp(op, "/ID") == 0) set_op(&op_ID, argv[i+1]);
if (strcmp(op, "/D") == 0) set_op(&op_D, argv[i+1]);
}
}
}

if (op_L==NULL || op_T==NULL || op_SO==NULL || op_ID==NULL || op_D==NULL) {
printf("gimme correct words.\n");
exit(1);
}

set_registry();
report_event();
unset_registry();

return 0;
}

(追記10/24: バグ見つけたので修正)