Fixed prototype for MmSetAddressRangeModified().
[reactos.git] / ntoskrnl / kd / dlog.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/kd/kdebug.c
6  * PURPOSE:         Kernel debugger
7  * PROGRAMMER:      Eric Kohl (ekohl@abo.rhein-zeitung.de)
8  * UPDATE HISTORY:
9  *                  21/10/99: Created
10  */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ntoskrnl.h>
16 #include <roscfg.h>
17 #include <internal/kd.h>
18 #include <ntos/minmax.h>
19
20 /* GLOBALS *******************************************************************/
21
22 #define DEBUGLOG_SIZE (32*1024)
23
24 #ifdef DBGPRINT_FILE_LOG
25
26 static CHAR DebugLog[DEBUGLOG_SIZE];
27 static ULONG DebugLogStart;
28 static ULONG DebugLogEnd;
29 static ULONG DebugLogCount;
30 static KSPIN_LOCK DebugLogLock;
31 static ULONG DebugLogOverflow;
32 static HANDLE DebugLogThreadHandle;
33 static CLIENT_ID DebugLogThreadCid;
34 static HANDLE DebugLogFile;
35 static KSEMAPHORE DebugLogSem;
36
37 #endif /* DBGPRINT_FILE_LOG */
38
39 /* FUNCTIONS *****************************************************************/
40
41 #ifdef DBGPRINT_FILE_LOG
42
43 VOID
44 DebugLogInit(VOID)
45 {
46   KeInitializeSpinLock(&DebugLogLock);
47   DebugLogStart = 0;
48   DebugLogEnd = 0;
49   DebugLogOverflow = 0;
50   DebugLogCount = 0;
51   KeInitializeSemaphore(&DebugLogSem, 0, 255);
52 }
53
54 NTSTATUS
55 DebugLogThreadMain(PVOID Context)
56 {
57   KIRQL oldIrql;
58   IO_STATUS_BLOCK Iosb;
59   static CHAR Buffer[256];
60   ULONG WLen;
61
62   for (;;)
63     {
64       KeWaitForSingleObject(&DebugLogSem,
65                             0,
66                             KernelMode,
67                             FALSE,
68                             NULL);
69       KeAcquireSpinLock(&DebugLogLock, &oldIrql);
70       while (DebugLogCount > 0)
71         {
72           if (DebugLogStart > DebugLogEnd)
73             {
74               WLen = min(256, DEBUGLOG_SIZE - DebugLogStart);
75               memcpy(Buffer, &DebugLog[DebugLogStart], WLen);
76               DebugLogStart = 
77                 (DebugLogStart + WLen) % DEBUGLOG_SIZE;
78               DebugLogCount = DebugLogCount - WLen;
79               KeReleaseSpinLock(&DebugLogLock, oldIrql);
80               NtWriteFile(DebugLogFile,
81                           NULL,
82                           NULL,
83                           NULL,
84                           &Iosb,
85                           Buffer,
86                           WLen,
87                           NULL,
88                           NULL);
89             }
90           else
91             {
92               WLen = min(256, DebugLogEnd - DebugLogStart);
93               memcpy(Buffer, &DebugLog[DebugLogStart], WLen);
94               DebugLogStart = 
95                 (DebugLogStart + WLen) % DEBUGLOG_SIZE;
96               DebugLogCount = DebugLogCount - WLen;
97               KeReleaseSpinLock(&DebugLogLock, oldIrql);
98               NtWriteFile(DebugLogFile,
99                           NULL,
100                           NULL,
101                           NULL,
102                           &Iosb,
103                           Buffer,
104                           WLen,
105                           NULL,
106                           NULL);
107             }
108           KeAcquireSpinLock(&DebugLogLock, &oldIrql);
109         }
110       KeReleaseSpinLock(&DebugLogLock, oldIrql);
111     }
112 }
113
114 VOID
115 DebugLogInit2(VOID)
116 {
117   NTSTATUS Status;
118   OBJECT_ATTRIBUTES ObjectAttributes;
119   UNICODE_STRING FileName;
120   IO_STATUS_BLOCK Iosb;
121
122   RtlInitUnicodeStringFromLiteral(&FileName, L"\\SystemRoot\\debug.log");
123   InitializeObjectAttributes(&ObjectAttributes,
124                              &FileName,
125                              0,
126                              NULL,
127                              NULL);
128                              
129   Status = NtCreateFile(&DebugLogFile,
130                         FILE_ALL_ACCESS,
131                         &ObjectAttributes,
132                         &Iosb,
133                         NULL,
134                         FILE_ATTRIBUTE_NORMAL,
135                         0,
136                         FILE_SUPERSEDE,
137                         FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
138                         NULL,
139                         0);
140   if (!NT_SUCCESS(Status))
141     {
142       DbgPrint("Failed to create debug log file\n");
143       return;
144     }
145
146   Status = PsCreateSystemThread(&DebugLogThreadHandle,
147                                 THREAD_ALL_ACCESS,
148                                 NULL,
149                                 NULL,
150                                 &DebugLogThreadCid,
151                                 DebugLogThreadMain,
152                                 NULL);
153 }
154
155  VOID 
156  DebugLogWrite(PCH String)
157  {
158    KIRQL oldIrql;
159
160    if (KeGetCurrentIrql() > DISPATCH_LEVEL)
161      {
162        DebugLogOverflow++;
163        return;
164      }
165
166    KeAcquireSpinLock(&DebugLogLock, &oldIrql);
167
168    if (DebugLogCount == DEBUGLOG_SIZE)
169      {
170        DebugLogOverflow++;
171        KeReleaseSpinLock(&DebugLogLock, oldIrql);
172        if (oldIrql < DISPATCH_LEVEL)
173          {
174            KeReleaseSemaphore(&DebugLogSem, IO_NO_INCREMENT, 1, FALSE);
175          }
176        return;
177      }
178
179    while ((*String) != 0)
180      {
181        DebugLog[DebugLogEnd] = *String;
182        String++;
183        DebugLogCount++;
184        if (DebugLogCount == DEBUGLOG_SIZE)
185          {         
186            DebugLogOverflow++;
187            KeReleaseSpinLock(&DebugLogLock, oldIrql);
188            if (oldIrql < DISPATCH_LEVEL)
189              {
190                KeReleaseSemaphore(&DebugLogSem, IO_NO_INCREMENT, 1, FALSE);
191              }
192            return;
193          }
194       DebugLogEnd = (DebugLogEnd + 1) % DEBUGLOG_SIZE;
195      }
196
197    KeReleaseSpinLock(&DebugLogLock, oldIrql);
198    if (oldIrql < DISPATCH_LEVEL)
199      {
200        KeReleaseSemaphore(&DebugLogSem, IO_NO_INCREMENT, 1, FALSE);
201      }
202  }
203
204  #else /* not DBGPRINT_FILE_LOG */
205
206  VOID
207  DebugLogInit(VOID)
208  {
209  }
210
211 VOID
212 DebugLogInit2(VOID)
213 {
214 }
215
216 VOID
217 DebugLogWrite(PCH String)
218 {
219 }
220
221 #endif /* DBGPRINT_FILE_LOG */
222