8 #define BUF_MAX_SIZE 128
\r
10 typedef struct _logEntry {
\r
11 LIST_ENTRY listEntry;
\r
15 static LIST_ENTRY s_logList;
\r
16 static KSPIN_LOCK s_logListLock;
\r
19 void mayuLogInit(const char *message)
\r
21 InitializeListHead(&s_logList);
\r
22 KeInitializeSpinLock(&s_logListLock);
\r
24 mayuLogEnque(message);
\r
30 IoReleaseCancelSpinLock(s_irp->CancelIrql);
\r
31 s_irp->IoStatus.Status = STATUS_CANCELLED;
\r
32 s_irp->IoStatus.Information = 0;
\r
33 IoCompleteRequest(s_irp, IO_NO_INCREMENT);
\r
38 void mayuLogEnque(const char *fmt, ...)
\r
42 ANSI_STRING ansiBuf;
\r
43 UNICODE_STRING unicodeBuf;
\r
44 CHAR buf[BUF_MAX_SIZE] = "";
\r
45 WCHAR wbuf[BUF_MAX_SIZE] = L"";
\r
48 PUNICODE_STRING punicode;
\r
50 entry = (logEntry*)ExAllocatePool(NonPagedPool, sizeof(logEntry));
\r
53 entry->log.Length = 0;
\r
54 entry->log.MaximumLength = BUF_MAX_SIZE;
\r
55 entry->log.Buffer = (PWSTR)ExAllocatePool(NonPagedPool, BUF_MAX_SIZE);
\r
57 unicodeBuf.Length = 0;
\r
58 unicodeBuf.MaximumLength = BUF_MAX_SIZE;
\r
59 unicodeBuf.Buffer = wbuf;
\r
62 ansiBuf.MaximumLength = BUF_MAX_SIZE;
\r
63 ansiBuf.Buffer = buf;
\r
65 va_start(argp, fmt);
\r
66 for (i = j = 0; i < BUF_MAX_SIZE; ++i) {
\r
67 ansiBuf.Buffer[i - j] = fmt[i];
\r
68 if (fmt[i] == '\0') {
\r
69 ansiBuf.Length = i - j;
\r
70 RtlAnsiStringToUnicodeString(&unicodeBuf, &ansiBuf, FALSE);
\r
71 RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);
\r
74 if (fmt[i] == '%') {
\r
75 ansiBuf.Length = i - j;
\r
76 RtlAnsiStringToUnicodeString(&unicodeBuf, &ansiBuf, FALSE);
\r
77 RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);
\r
80 ul = va_arg(argp, ULONG);
\r
81 RtlIntegerToUnicodeString(ul, 16, &unicodeBuf);
\r
82 RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);
\r
85 ul = va_arg(argp, ULONG);
\r
86 RtlIntegerToUnicodeString(ul, 10, &unicodeBuf);
\r
87 RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);
\r
90 punicode = va_arg(argp, PUNICODE_STRING);
\r
91 RtlAppendUnicodeStringToString(&entry->log, punicode);
\r
98 ExInterlockedInsertTailList(&s_logList, &entry->listEntry, &s_logListLock);
\r
103 mayuLogDeque(s_irp);
\r
104 IoAcquireCancelSpinLock(&cancelIrql);
\r
105 IoSetCancelRoutine(s_irp, NULL);
\r
106 IoReleaseCancelSpinLock(cancelIrql);
\r
107 IoCompleteRequest(s_irp, IO_NO_INCREMENT);
\r
112 VOID mayuLogCancel(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
\r
115 IoReleaseCancelSpinLock(irp->CancelIrql);
\r
116 irp->IoStatus.Status = STATUS_CANCELLED;
\r
117 irp->IoStatus.Information = 0;
\r
118 IoCompleteRequest(irp, IO_NO_INCREMENT);
\r
121 NTSTATUS mayuLogDeque(PIRP irp)
\r
125 KeAcquireSpinLock(&s_logListLock, ¤tIrql);
\r
126 if (IsListEmpty(&s_logList) == TRUE) {
\r
129 IoAcquireCancelSpinLock(&cancelIrql);
\r
130 IoMarkIrpPending(irp);
\r
132 IoSetCancelRoutine(irp, mayuLogCancel);
\r
133 IoReleaseCancelSpinLock(cancelIrql);
\r
134 KeReleaseSpinLock(&s_logListLock, currentIrql);
\r
135 irp->IoStatus.Information = 0;
\r
136 irp->IoStatus.Status = STATUS_PENDING;
\r
138 PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
\r
139 PLIST_ENTRY pListEntry;
\r
142 KeReleaseSpinLock(&s_logListLock, currentIrql);
\r
143 pListEntry = ExInterlockedRemoveHeadList(&s_logList, &s_logListLock);
\r
144 pEntry = CONTAINING_RECORD(pListEntry, logEntry, listEntry);
\r
145 RtlCopyMemory(irp->AssociatedIrp.SystemBuffer,
\r
146 pEntry->log.Buffer, pEntry->log.Length);
\r
147 irp->IoStatus.Information = pEntry->log.Length;
\r
148 irp->IoStatus.Status = STATUS_SUCCESS;
\r
149 ExFreePool(pEntry->log.Buffer);
\r
150 ExFreePool(pEntry);
\r
152 return irp->IoStatus.Status;
\r