1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
vrdebug.h
Abstract:
Contains defines for Vdm Redir Debugging info
Author:
Richard L Firth (rfirth) 13-Feb-1992
Notes:
Add new category for each new group of functions added for which external
debug control is required
Revision History:
--*/
//
// COMPILE-time debugging options:
// definitions for debug flags. Each bit enables diagnostic printing/specific
// debugging of corresponding module. Also overridden at run-time in DBG
// version by having these flags in the VR= environment variable
//
#define DEBUG_MAILSLOT 0x00000001L // general Mailslots
#define DEBUG_NAMEPIPE 0x00000002L // general Named Pipe
#define DEBUG_NETAPI 0x00000004L // general NETAPI
#define DEBUG_NETBIOS 0x00000008L // general NETBIOS
#define DEBUG_DLC 0x00000010L // general DLC
#define DEBUG_DOS_CCB_IN 0x00000020L // input DOS CCBs & parameter tables
#define DEBUG_DOS_CCB_OUT 0x00000040L // output DOS CCBs & parameter tables
#define DEBUG_NT_CCB_IN 0x00000080L // input NT CCBs & parameter tables
#define DEBUG_NT_CCB_OUT 0x00000100L // output NT CCBs & parameter tables
#define DEBUG_DLC_BUFFERS 0x00000200L // DLC buffer pools
#define DEBUG_DLC_TX_DATA 0x00000400L // DLC transmit data
#define DEBUG_DLC_RX_DATA 0x00000800L // DLC received data
#define DEBUG_DLC_ASYNC 0x00001000L // DLC async call-backs
#define DEBUG_TRANSACT_TX 0x00002000L // Transaction send data buffer(s)
#define DEBUG_TRANSACT_RX 0x00004000L // Transaction receive data buffer(s)
#define DEBUG_DLC_ALLOC 0x00008000L // dump alloc/free calls in DLC
#define DEBUG_READ_COMPLETE 0x00010000L // dump CCB when READ completes
#define DEBUG_ASYNC_EVENT 0x00020000L // dump asynchronous event info
#define DEBUG_CMD_COMPLETE 0x00040000L // dump command complete event info
#define DEBUG_TX_COMPLETE 0x00080000L // dump transmit complete event info
#define DEBUG_RX_DATA 0x00100000L // dump data received event info
#define DEBUG_STATUS_CHANGE 0x00200000L // dump DLC status change event info
#define DEBUG_EVENT_QUEUE 0x00400000L // dump PutEvent, GetEvent and PeekEvent
#define DEBUG_DOUBLE_TICKS 0x00800000L // multiply timer tick counts by 2
#define DEBUG_DUMP_FREE_BUF 0x01000000L // dump buffer header on BUFFER.FREE
#define DEBUG_CRITSEC 0x02000000L // dump enter/leave critical section info
#define DEBUG_SUPERCRITICAL 0x04000000L // dump only stuff we absolutely need to know
#define DEBUG_CRITICAL 0x08000000L // where #ifdef CRITICAL_DEBUGGING used to be
#define DEBUG_TIME 0x10000000L // display relative time of events
#define DEBUG_TO_FILE 0x20000000L // dump output to file VRDEBUG.LOG
#define DEBUG_DLL 0x40000000L // general DLL stuff - init, terminate
#define DEBUG_BREAKPOINT 0x80000000L // break everywhere there's a DEBUG_BREAK
#define DEBUG_DOS_CCB (DEBUG_DOS_CCB_IN | DEBUG_DOS_CCB_OUT)
#define VRDEBUG_FILE "VRDEBUG.LOG"
#if DBG
#include <stdio.h>
//extern DWORD VrDebugFlags;
DWORD VrDebugFlags;
extern FILE* hVrDebugLog;
extern VOID DbgOut(LPSTR, ...);
#define IF_DEBUG(type) if (VrDebugFlags & DEBUG_##type)
#define DEBUG_BREAK() IF_DEBUG(BREAKPOINT) { \
DbgPrint("BP %s.%d\n", __FILE__, __LINE__); \
DbgBreakPoint(); \
}
#define DBGPRINT DbgOut
#define DPUT(s) DBGPRINT(s)
#define DPUT1(s, a) DBGPRINT(s, a)
#define DPUT2(s, a, b) DBGPRINT(s, a, b)
#define DPUT3(s, a, b, c) DBGPRINT(s, a, b, c)
#define DPUT4(s, a, b, c, d) DBGPRINT(s, a, b, c, d)
#define DPUT5(s, a, b, c, d, e) DBGPRINT(s, a, b, c, d, e)
#define CRITDUMP(x) DbgPrint x
#define DUMPCCB DumpCcb
#else
#define IF_DEBUG(type) if (0)
#define DEBUG_BREAK()
#define DBGPRINT
#define DPUT(s)
#define DPUT1(s, a)
#define DPUT2(s, a, b)
#define DPUT3(s, a, b, c)
#define DPUT4(s, a, b, c, d)
#define DPUT5(s, a, b, c, d, e)
#define CRITDUMP(x)
#define DUMPCCB
#endif
//
// defaults
//
#define DEFAULT_STACK_DUMP 32
//
// numbers
//
#define NUMBER_OF_VR_GROUPS 5
#define NUMBER_OF_CPU_REGISTERS 14
#define MAX_ID_LEN 40
#define MAX_DESC_LEN 256
//
// environment strings - shortened since they all go through to dos & dos can
// only handle 1K of environment
//
#define ES_VRDEBUG "VRDBG" // "__VRDEBUG"
#define ES_MAILSLOT "MS" // "MAILSLOT"
#define ES_NAMEPIPE "NP" // "NAMEPIPE"
#define ES_LANMAN "LM" // "LANMAN"
#define ES_NETBIOS "NB" // "NETBIOS"
#define ES_DLC "DLC" // "DLC"
//
// diagnostic controls - in same numerical order as TOKEN!!!
//
#define DC_BREAK "BRK" // "BREAK"
#define DC_DISPLAYNAME "DN" // "DISPLAYNAME"
#define DC_DLC ES_DLC
#define DC_DUMPMEM "DM" // "DUMPMEM"
#define DC_DUMPREGS "DR" // "DUMPREGS"
#define DC_DUMPSTACK "DK" // "DUMPSTACK"
#define DC_DUMPSTRUCT "DS" // "DUMPSTRUCT"
#define DC_ERROR "E" // "ERROR"
#define DC_ERRORBREAK "EB" // "ERRORBREAK"
#define DC_INFO "I" // "INFO"
#define DC_LANMAN ES_LANMAN
#define DC_MAILSLOT ES_MAILSLOT
#define DC_NAMEPIPE ES_NAMEPIPE
#define DC_NETBIOS ES_NETBIOS
#define DC_PAUSEBREAK "PB" // "PAUSEBREAK"
#define DC_WARN "W" // "WARN"
//
// diagnostic categories (groups)
//
#define DG_ALL -1L // catch first enabled set
#define DG_NONE 0 // no category
#define DG_MAILSLOT 0x00000001L
#define DG_NAMEPIPE 0x00000002L
#define DG_LANMAN 0x00000004L
#define DG_NETBIOS 0x00000008L
#define DG_DLC 0x00000010L
//
// diagnostic index (in VrDiagnosticGroups array)
//
#define DI_MAILSLOT 0
#define DI_NAMEPIPE 1
#define DI_LANMAN 2
#define DI_NETBIOS 3
#define DI_DLC 4
//
// diagnostic control manifests
//
#define DM_INFORMATION 0x00010000L // display all info, warning and error messages
#define DM_WARNING 0x00020000L // display warning and error messages
#define DM_ERROR 0x00030000L // display error messages only
#define DM_ERRORBREAK 0x00100000L // DbgBreakPoint() on error
#define DM_PAUSEBREAK 0x00200000L // DbgBreakPoint() on pause (wait for developer)
#define DM_DUMPREGS 0x00800000L // dump x86 registers when routine entered
#define DM_DUMPREGSDBG 0x01000000L // dump x86 registers when routine entered, debug style
#define DM_DUMPMEM 0x02000000L // dump DOS memory when routine entered
#define DM_DUMPSTACK 0x04000000L // dump DOS stack when routine entered
#define DM_DUMPSTRUCT 0x08000000L // dump a structure when routine entered
#define DM_DISPLAYNAME 0x10000000L // display the function name
#define DM_BREAK 0x80000000L // break when routine entered
#define DM_DISPLAY_MASK 0x000f0000L
//
// enumerated types
//
////
//// GPREG - General Purpose REGisters
////
//
//typedef enum {
// AX = 0,
// BX,
// CX,
// DX,
// SI,
// DI,
// BP,
// SP
//} GPREG;
//
////
//// SEGREG - SEGment REGisters
////
//
//typedef enum {
// CS = 8,
// DS,
// ES,
// SS
//} SEGREG;
//
////
//// SPREG - Special Purpose REGisters
////
//
//typedef enum {
// IP = 12,
// FLAGS
//} SPREG;
//
//typedef union {
// SEGREG SegReg;
// GPREG GpReg;
// SPREG SpReg;
//} REGISTER;
typedef enum {
AX = 0,
BX = 1,
CX = 2,
DX = 3,
SI = 4,
DI = 5,
BP = 6,
SP = 7,
CS = 8,
DS = 9,
ES = 10,
SS = 11,
IP = 12,
FLAGS = 13
} REGISTER;
//
// REGVAL - keeps a 16-bit value or a register specification, depending on
// sense of IsRegister
//
typedef struct {
BOOL IsRegister;
union {
REGISTER Register;
WORD Value;
} RegOrVal;
} REGVAL, *LPREGVAL;
//
// structures
//
//
// CONTROL - keeps correspondence between control keyword and control flag
//
typedef struct {
char* Keyword;
DWORD Flag;
} CONTROL;
//
// OPTION - keeps correspondence between diagnostic option and option type
//
typedef struct {
char* Keyword;
DWORD Flag;
} OPTION;
//
// REGDEF - defines a register - keeps correspondence between name and type
//
typedef struct {
char RegisterName[3];
REGISTER Register;
} REGDEF, *LPREGDEF;
//
// GROUPDEF - keeps correspondence between group name and index in
// VrDiagnosticGroups array
//
typedef struct {
char* Name;
DWORD Index;
} GROUPDEF;
//
// MEMORY_INFO - for each each memory dump we keep a record of its type, length
// and starting address
//
typedef struct _MEMORY_INFO {
struct _MEMORY_INFO* Next;
REGVAL Segment;
REGVAL Offset;
REGVAL DumpCount;
BYTE DumpType;
} MEMORY_INFO, *LPMEMORY_INFO;
//
// STRUCT_INFO - for each structure to be dumped we keep record of the segment
// and offset registers and the string which describes the structure to be
// dumped. The descriptor is similar to (but NOT THE SAME AS) the Rap
// descriptor stuff
//
typedef struct _STRUCT_INFO {
struct _STRUCTINFO* Next;
char StructureDescriptor[MAX_DESC_LEN+1];
REGVAL Segment;
REGVAL Offset;
} STRUCT_INFO, *LPSTRUCT_INFO;
//
// DIAGNOSTIC_INFO - information common to GROUP_DIAGNOSTIC and FUNCTION_DIAGNOSTIC
//
typedef struct {
DWORD OnControl;
DWORD OffControl;
MEMORY_INFO StackInfo; // special case of MemoryInfo
MEMORY_INFO MemoryInfo;
STRUCT_INFO StructInfo;
} DIAGNOSTIC_INFO, *LPDIAGNOSTIC_INFO;
//
// GROUP_DIAGNOSTIC - because the groups are predefined, we don't keep any
// name information, or a list - just NUMBER_OF_VR_GROUPS elements in an
// array of GROUP_DIAGNOSTIC structures
//
typedef struct {
char GroupName[MAX_ID_LEN+1];
DIAGNOSTIC_INFO Diagnostic;
} GROUP_DIAGNOSTIC, *LPGROUP_DIAGNOSTIC;
//
// FUNCTION_DIAGNOSTIC - if we want to diagnose a particular named function,
// then we generate one of these. We keep a (unsorted) list of these if a
// function description is parsed from the environment string(s)
//
typedef struct _FUNCTION_DIAGNOSTIC {
struct _FUNCTION_DIAGNOSTIC* Next;
char FunctionName[MAX_ID_LEN+1];
DIAGNOSTIC_INFO Diagnostic;
} FUNCTION_DIAGNOSTIC, *LPFUNCTION_DIAGNOSTIC;
//
// structure descriptor characters (general purpose data descriptors)
//
#define SD_BYTE 'B' // 8-bits, displayed as hex (0a)
#define SD_WORD 'W' // 16-bits, displayed as hex (0abc)
#define SD_DWORD 'D' // 32-bits, displayed as hex (0abc1234)
#define SD_POINTER 'P' // 32-bits, displayed as pointer (0abc:1234)
#define SD_ASCIZ 'A' // asciz string, displayed as string "this is a string"
#define SD_ASCII 'a' // asciz pointer, displayed as pointer, string 0abc:1234 "this is a string"
#define SD_CHAR 'C' // ascii character, displayed as character 'c'
#define SD_NUM 'N' // 8-bits, displayed as unsigned byte (0 to 255)
#define SD_INT 'I' // 16-bits, displayed as unsigned word (0 to 65,535)
#define SD_LONG 'L' // 32-bits, displayed as unsigned long (0 to 4,294,967,295)
#define SD_SIGNED '-' // convert I,L,N to signed
#define SD_DELIM ':' // name delimiter
#define SD_FIELDSEP ';' // separates named fields
#define SD_NAMESEP '/' // separates structure name from fields
#define SD_CHARS {SD_BYTE, \
SD_WORD, \
SD_DWORD, \
SD_POINTER, \
SD_ASCIZ, \
SD_ASCII,\
SD_CHAR, \
SD_NUM, \
SD_INT, \
SD_LONG, \
SD_SIGNED}
#define MD_CHARS {SD_BYTE, SD_WORD, SD_DWORD, SD_POINTER}
//
// token stuff
//
//
// TOKEN - enumerated, alphabetically ordered tokens
//
typedef enum {
TLEFTPAREN = -6, // (
TRIGHTPAREN = -5, // )
TREGISTER = -4,
TNUMBER = -3,
TEOS = -2, // end of string
TUNKNOWN = -1, // unknown lexeme, assume routine name?
//
// tokens from here on down are also the index into DiagnosticTokens which
// describe them
//
TBREAK = 0,
TDISPLAYNAME,
TDLC,
TDUMPMEM,
TDUMPREGS,
TDUMPSTACK,
TDUMPSTRUCT,
TERROR,
TERRORBREAK,
TINFO,
TLANMAN,
TMAILSLOT,
TNAMEPIPE,
TNETBIOS,
TPAUSEBREAK,
TWARN
} TOKEN;
//
// TIB (Token Info Bucket) - Contains info describing token found. Only filled
// in when we find an identifier, number or a register
//
typedef struct {
LPSTR TokenStream;
TOKEN Token;
union {
REGVAL RegVal;
char Id[MAX_DESC_LEN+1];
} RegValOrId;
} TIB, *LPTIB;
//
// DEBUG_TOKEN - maps from lexeme to token
//
typedef struct {
char* TokenString;
TOKEN Token;
} DEBUG_TOKEN;
//
// what to expect when parsing strings
//
#define EXPECTING_NOTHING 0x00
#define EXPECTING_REGVAL 0x01
#define EXPECTING_MEMDESC 0x02
#define EXPECTING_STRUCTDESC 0x04
#define EXPECTING_LEFTPAREN 0x08
#define EXPECTING_RIGHTPAREN 0x10
#define EXPECTING_EOS 0x20
#define EXPECTING_NO_ARGS 0x40
//
// data (defined in vrdebug.c)
//
//
// VrDiagnosticGroups - an array of GROUP_DIAGNOSTIC structures
//
GROUP_DIAGNOSTIC VrDiagnosticGroups[NUMBER_OF_VR_GROUPS];
//
// FunctionList - linked list of FUNCTION_DIAGNOSTIC structures
//
LPFUNCTION_DIAGNOSTIC FunctionList;
//
// prototypes (in vrdebug.c)
//
VOID
VrDebugInit(
VOID
);
LPDIAGNOSTIC_INFO
VrDiagnosticEntryPoint(
IN LPSTR FunctionName,
IN DWORD FunctionCategory,
OUT LPDIAGNOSTIC_INFO Info
);
VOID
VrPauseBreak(
LPDIAGNOSTIC_INFO Info
);
VOID
VrErrorBreak(
LPDIAGNOSTIC_INFO Info
);
VOID
VrPrint(
IN DWORD Level,
IN LPDIAGNOSTIC_INFO Context,
IN LPSTR Format,
IN ...
);
VOID
VrDumpRealMode16BitRegisters(
IN BOOL DebugStyle
);
VOID
VrDumpDosMemory(
IN BYTE Type,
IN DWORD Iterations,
IN WORD Segment,
IN WORD Offset
);
VOID
VrDumpDosMemoryStructure(
IN LPSTR Descriptor,
IN WORD Segment,
IN WORD Offset
);
//
//VOID
//VrDumpDosStack(
// IN DWORD Depth
// )
//
///*++
//
//Routine Description:
//
// Dumps <Depth> words from the Vdm stack, as addressed by getSS():getSP().
// Uses VrDumpDosMemory to dump stack contents
//
//Arguments:
//
// Depth - number of 16-bit words to dump from DOS memory stack
//
//Return Value:
//
// None.
//
//--*/
//
#define VrDumpDosStack(Depth) VrDumpDosMemory('W', Depth, getSS(), getSP())
//
// macros used in routines to be diagnosed
//
#if DBG
#define DIAGNOSTIC_ENTRY VrDiagnosticEntryPoint
#define DIAGNOSTIC_EXIT VrDiagnosticExitPoint
#define BREAK_ON_PAUSE VrPauseBreak
#define BREAK_ON_ERROR VrErrorBreak
//#define INFORM(s, ...) VrPrint(DM_INFORMATION, s, ...)
//#define WARN(s, ...) VrPrint(DM_WARNING, s, ...)
//#define ERROR(s, ...) VrPrint(DM_ERROR, s, ...)
#else
//
// macros used in routines to be diagnosed - don't expand to anything in non-debug
//
#define DIAGNOSTIC_ENTRY
#define DIAGNOSTIC_EXIT
#define BREAK_ON_PAUSE
#define BREAK_ON_ERROR
//#define INFORM
//#define WARN
//#define ERROR
#endif
|