ReactOS 0.4.15-dev-7961-gdcf9eb0
device.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "cpu/bop.h"
#include "device.h"
#include "dos.h"
#include "dos/dem.h"
#include "memory.h"
Include dependency graph for device.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

 C_ASSERT ((sizeof(StrategyRoutine)+sizeof(InterruptRoutine))==DEVICE_CODE_SIZE)
 
static VOID DosCallDriver (DWORD Driver, PDOS_REQUEST_HEADER Request)
 
static WORD NTAPI DosDriverReadInternal (PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length, BOOLEAN IoControl)
 
static WORD NTAPI DosDriverWriteInternal (PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length, BOOLEAN IoControl)
 
static WORD NTAPI DosDriverGenericRequest (PDOS_DEVICE_NODE DeviceNode, BYTE CommandCode)
 
static WORD NTAPI DosDriverDispatchIoctlRead (PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
 
static WORD NTAPI DosDriverDispatchRead (PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
 
static WORD NTAPI DosDriverDispatchPeek (PDOS_DEVICE_NODE DeviceNode, PBYTE Character)
 
static WORD NTAPI DosDriverDispatchInputStatus (PDOS_DEVICE_NODE DeviceNode)
 
static WORD NTAPI DosDriverDispatchFlushInput (PDOS_DEVICE_NODE DeviceNode)
 
static WORD NTAPI DosDriverDispatchIoctlWrite (PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
 
static WORD NTAPI DosDriverDispatchWrite (PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
 
static WORD NTAPI DosDriverDispatchOutputStatus (PDOS_DEVICE_NODE DeviceNode)
 
static WORD NTAPI DosDriverDispatchFlushOutput (PDOS_DEVICE_NODE DeviceNode)
 
static WORD NTAPI DosDriverDispatchOpen (PDOS_DEVICE_NODE DeviceNode)
 
static WORD NTAPI DosDriverDispatchClose (PDOS_DEVICE_NODE DeviceNode)
 
static WORD NTAPI DosDriverDispatchOutputUntilBusy (PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
 
static VOID DosAddDriver (DWORD Driver)
 
static VOID DosRemoveDriver (DWORD Driver)
 
static PDOS_DEVICE_NODE DosCreateDeviceNode (DWORD Driver)
 
PDOS_DEVICE_NODE DosGetDriverNode (DWORD Driver)
 
PDOS_DEVICE_NODE DosGetDevice (LPCSTR DeviceName)
 
PDOS_DEVICE_NODE DosCreateDeviceEx (WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
 
PDOS_DEVICE_NODE DosCreateDevice (WORD Attributes, PCHAR DeviceName)
 
VOID DosDeleteDevice (PDOS_DEVICE_NODE DeviceNode)
 
VOID DeviceStrategyBop (VOID)
 
VOID DeviceInterruptBop (VOID)
 
DWORD DosLoadDriver (LPCSTR DriverFile)
 

Variables

static const BYTE StrategyRoutine []
 
static const BYTE InterruptRoutine []
 
static LIST_ENTRY DeviceList = { &DeviceList, &DeviceList }
 
static PDOS_REQUEST_HEADER DeviceRequest
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file device.c.

Function Documentation

◆ C_ASSERT()

◆ DeviceInterruptBop()

VOID DeviceInterruptBop ( VOID  )

Definition at line 436 of file device.c.

437{
440 DWORD DriverAddress = (getCS() << 4) + getIP() - sizeof(DOS_DRIVER) - 9;
441
442 /* Get the device node for this driver */
443 for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink)
444 {
446 if (TO_LINEAR(HIWORD(Node->Driver), LOWORD(Node->Driver)) == DriverAddress) break;
447 }
448
449 if (i == &DeviceList)
450 {
451 DPRINT1("Device interrupt BOP from an unknown location.\n");
452 return;
453 }
454
455 switch (DeviceRequest->CommandCode)
456 {
458 {
460
461 DeviceRequest->Status = Node->IoctlReadRoutine(
462 Node,
463 Request->BufferPointer,
464 &Request->Length
465 );
466
467 break;
468 }
469
470 case DOS_DEVCMD_READ:
471 {
473
474 DeviceRequest->Status = Node->ReadRoutine(
475 Node,
476 Request->BufferPointer,
477 &Request->Length
478 );
479
480 break;
481 }
482
483 case DOS_DEVCMD_PEEK:
484 {
486 DeviceRequest->Status = Node->PeekRoutine(Node, &Request->Character);
487 break;
488 }
489
491 {
492 DeviceRequest->Status = Node->InputStatusRoutine(Node);
493 break;
494 }
495
497 {
498 DeviceRequest->Status = Node->FlushInputRoutine(Node);
499 break;
500 }
501
503 {
505
506 DeviceRequest->Status = Node->IoctlWriteRoutine(
507 Node,
508 Request->BufferPointer,
509 &Request->Length
510 );
511
512 break;
513 }
514
515 case DOS_DEVCMD_WRITE:
516 {
518
519 DeviceRequest->Status = Node->WriteRoutine(Node,
520 Request->BufferPointer,
521 &Request->Length
522 );
523
524 break;
525 }
526
528 {
529 DeviceRequest->Status = Node->OutputStatusRoutine(Node);
530 break;
531 }
532
534 {
535 DeviceRequest->Status = Node->FlushOutputRoutine(Node);
536 break;
537 }
538
539 case DOS_DEVCMD_OPEN:
540 {
541 DeviceRequest->Status = Node->OpenRoutine(Node);
542 break;
543 }
544
545 case DOS_DEVCMD_CLOSE:
546 {
547 DeviceRequest->Status = Node->CloseRoutine(Node);
548 break;
549 }
550
552 {
554
555 DeviceRequest->Status = Node->OutputUntilBusyRoutine(
556 Node,
557 Request->BufferPointer,
558 &Request->Length
559 );
560
561 break;
562 }
563
564 default:
565 {
566 DPRINT1("Unknown device command code: %u\n", DeviceRequest->CommandCode);
567 }
568 }
569}
#define DPRINT1
Definition: precomp.h:8
union node Node
Definition: types.h:1255
#define TO_LINEAR(seg, off)
Definition: emulator.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
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
#define LOWORD(l)
Definition: pedump.c:82
base of all file and directory entries
Definition: entries.h:83
OUT WORD Status
Definition: device.h:133
IN BYTE CommandCode
Definition: device.h:132
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
static PDOS_REQUEST_HEADER DeviceRequest
Definition: device.c:45
static LIST_ENTRY DeviceList
Definition: device.c:44
#define DOS_DEVCMD_OUTPUT_BUSY
Definition: device.h:47
#define DOS_DEVCMD_FLUSH_INPUT
Definition: device.h:38
struct _DOS_OUTPUT_BUSY_REQUEST * PDOS_OUTPUT_BUSY_REQUEST
#define DOS_DEVCMD_FLUSH_OUTPUT
Definition: device.h:42
struct _DOS_IOCTL_RW_REQUEST * PDOS_IOCTL_RW_REQUEST
#define DOS_DEVCMD_READ
Definition: device.h:35
#define DOS_DEVCMD_INSTAT
Definition: device.h:37
#define DOS_DEVCMD_IOCTL_WRITE
Definition: device.h:43
struct _DOS_PEEK_REQUEST * PDOS_PEEK_REQUEST
struct _DOS_DRIVER DOS_DRIVER
struct _DOS_RW_REQUEST * PDOS_RW_REQUEST
#define DOS_DEVCMD_PEEK
Definition: device.h:36
#define DOS_DEVCMD_WRITE
Definition: device.h:39
#define DOS_DEVCMD_IOCTL_READ
Definition: device.h:34
#define DOS_DEVCMD_CLOSE
Definition: device.h:45
#define DOS_DEVCMD_OUTSTAT
Definition: device.h:41
#define DOS_DEVCMD_OPEN
Definition: device.h:44
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define HIWORD(l)
Definition: typedefs.h:247
Definition: dlist.c:348
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

Referenced by DosSystemBop().

◆ DeviceStrategyBop()

VOID DeviceStrategyBop ( VOID  )

Definition at line 430 of file device.c.

431{
432 /* Save ES:BX */
434}
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
struct _DOS_REQUEST_HEADER * PDOS_REQUEST_HEADER
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
USHORT WINAPI getES(VOID)
Definition: registers.c:522

Referenced by DosSystemBop().

◆ DosAddDriver()

static VOID DosAddDriver ( DWORD  Driver)
static

Definition at line 228 of file device.c.

229{
230 PDOS_DRIVER LastDriver = &SysVars->NullDevice;
231
232 /* Find the last driver in the list */
233 while (LOWORD(LastDriver->Link) != 0xFFFF)
234 {
235 LastDriver = (PDOS_DRIVER)FAR_POINTER(LastDriver->Link);
236 }
237
238 /* Add the new driver to the list */
239 LastDriver->Link = Driver;
240 LastDriver = (PDOS_DRIVER)FAR_POINTER(Driver);
241
242 if (LastDriver->DeviceAttributes & DOS_DEVATTR_CLOCK)
243 {
244 /* Update the active CLOCK driver */
246 }
247
248 if (LastDriver->DeviceAttributes
250 {
251 /* Update the active CON driver */
253 }
254}
PDOS_SYSVARS SysVars
Definition: dos.c:47
#define FAR_POINTER(x)
Definition: emulator.h:35
DWORD Link
Definition: device.h:110
WORD DeviceAttributes
Definition: device.h:111
DWORD ActiveCon
Definition: dos.h:83
DWORD ActiveClock
Definition: dos.h:82
DOS_DRIVER NullDevice
Definition: dos.h:89
#define DOS_DEVATTR_STDIN
Definition: device.h:21
#define DOS_DEVATTR_CLOCK
Definition: device.h:24
#define DOS_DEVATTR_CON
Definition: device.h:25
#define DOS_DEVATTR_STDOUT
Definition: device.h:22
struct _DOS_DRIVER * PDOS_DRIVER
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83

Referenced by DosCreateDeviceEx(), and DosLoadDriver().

◆ DosCallDriver()

static VOID DosCallDriver ( DWORD  Driver,
PDOS_REQUEST_HEADER  Request 
)
static

Definition at line 49 of file device.c.

50{
52 WORD AX = getAX();
53 WORD CX = getCX();
54 WORD DX = getDX();
55 WORD BX = getBX();
56 WORD BP = getBP();
57 WORD SI = getSI();
58 WORD DI = getDI();
59 WORD DS = getDS();
60 WORD ES = getES();
61
62 /* Set ES:BX to the location of the request */
65
66 /* Copy the request structure to ES:BX */
67 RtlMoveMemory(&Sda->Request, Request, Request->RequestLength);
68
69 /* Call the strategy routine, and then the interrupt routine */
72
73 /* Get the request structure from ES:BX */
74 RtlMoveMemory(Request, &Sda->Request, Request->RequestLength);
75
76 /* Restore the registers */
77 setAX(AX);
78 setCX(CX);
79 setDX(DX);
80 setBX(BX);
81 setBP(BP);
82 setSI(SI);
83 setDI(DI);
84 setDS(DS);
85 setES(ES);
86}
@ DS
Definition: amd64_sup.c:16
PDOS_SDA Sda
Definition: dos.c:48
CALLBACK16 DosContext
Definition: dos.c:40
unsigned short WORD
Definition: ntddk_ex.h:93
#define DX
Definition: i386-dis.c:425
#define AX
Definition: i386-dis.c:424
@ ES
Definition: bidi.c:78
WORD StrategyRoutine
Definition: device.h:112
WORD InterruptRoutine
Definition: device.h:113
DOS_RW_REQUEST Request
Definition: dos.h:193
VOID RunCallback16(IN PCALLBACK16 Context, IN ULONG FarPtr)
Definition: callback.c:93
#define DOS_DATA_OFFSET(x)
Definition: dos.h:35
#define DOS_DATA_SEGMENT
Definition: dos.h:33
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
USHORT WINAPI getBP(VOID)
Definition: registers.c:374
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
VOID WINAPI setBP(USHORT)
Definition: registers.c:381
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID WINAPI setES(USHORT)
Definition: registers.c:529
VOID WINAPI setSI(USHORT)
Definition: registers.c:411
VOID WINAPI setDI(USHORT)
Definition: registers.c:441

Referenced by DosDriverDispatchOutputUntilBusy(), DosDriverDispatchPeek(), DosDriverGenericRequest(), DosDriverReadInternal(), DosDriverWriteInternal(), and DosLoadDriver().

◆ DosCreateDevice()

PDOS_DEVICE_NODE DosCreateDevice ( WORD  Attributes,
PCHAR  DeviceName 
)

Definition at line 413 of file device.c.

414{
415 /* Call the extended API */
417}
PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
Definition: device.c:361
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275

Referenced by ConDrvInitialize().

◆ DosCreateDeviceEx()

PDOS_DEVICE_NODE DosCreateDeviceEx ( WORD  Attributes,
PCHAR  DeviceName,
WORD  PrivateDataSize 
)

Definition at line 361 of file device.c.

362{
363 BYTE i;
365 PDOS_DRIVER DriverHeader;
367
368 /* Make sure this is a character device */
370 {
371 DPRINT1("ERROR: Block devices are not supported.\n");
372 return NULL;
373 }
374
375 /* Create a driver header for this device */
376 Segment = DosAllocateMemory(sizeof(DOS_DRIVER) + DEVICE_CODE_SIZE + PrivateDataSize, NULL);
377 if (Segment == 0) return NULL;
378
379 /* Fill the header with data */
380 DriverHeader = SEG_OFF_TO_PTR(Segment, 0);
381 DriverHeader->Link = MAXDWORD;
382 DriverHeader->DeviceAttributes = Attributes;
383 DriverHeader->StrategyRoutine = sizeof(DOS_DRIVER);
384 DriverHeader->InterruptRoutine = sizeof(DOS_DRIVER) + sizeof(StrategyRoutine);
385
386 RtlFillMemory(DriverHeader->DeviceName, MAX_DEVICE_NAME, ' ');
387 for (i = 0; i < MAX_DEVICE_NAME; i++)
388 {
389 if (DeviceName[i] == '\0' || DeviceName[i] == ' ') break;
390 DriverHeader->DeviceName[i] = DeviceName[i];
391 }
392
393 /* Write the routines */
396 sizeof(StrategyRoutine));
399 sizeof(InterruptRoutine));
400
401 /* Create the node */
403 if (Node == NULL)
404 {
406 return NULL;
407 }
408
409 DosAddDriver(Node->Driver);
410 return Node;
411}
#define NULL
Definition: types.h:112
#define MAX_DEVICE_NAME
Definition: fdc.h:14
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define MAXDWORD
CHAR DeviceName[MAX_DEVICE_NAME]
Definition: device.h:117
static VOID DosAddDriver(DWORD Driver)
Definition: device.c:228
static const BYTE InterruptRoutine[]
Definition: device.c:34
static const BYTE StrategyRoutine[]
Definition: device.c:26
static PDOS_DEVICE_NODE DosCreateDeviceNode(DWORD Driver)
Definition: device.c:275
#define DEVICE_CODE_SIZE
Definition: device.h:15
#define DOS_DEVATTR_CHARACTER
Definition: device.h:29
WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
Definition: memory.c:136
BOOLEAN DosFreeMemory(WORD BlockData)
Definition: memory.c:418
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
unsigned char BYTE
Definition: xxhash.c:193

Referenced by DosCreateDevice(), EmsDrvInitialize(), and XmsInitialize().

◆ DosCreateDeviceNode()

static PDOS_DEVICE_NODE DosCreateDeviceNode ( DWORD  Driver)
static

Definition at line 275 of file device.c.

276{
277 BYTE i;
278 PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(Driver);
279 PDOS_DEVICE_NODE Node = RtlAllocateHeap(RtlGetProcessHeap(),
281 sizeof(*Node));
282 if (Node == NULL) return NULL;
283
284 Node->Driver = Driver;
285 Node->DeviceAttributes = DriverHeader->DeviceAttributes;
286
287 /* Initialize the name string */
288 Node->Name.Buffer = Node->NameBuffer;
289 Node->Name.MaximumLength = MAX_DEVICE_NAME;
290
291 for (i = 0; i < MAX_DEVICE_NAME; i++)
292 {
293 if (DriverHeader->DeviceName[i] == ' ') break;
294 Node->Name.Buffer[i] = DriverHeader->DeviceName[i];
295 }
296
297 Node->Name.Length = i;
298
299 InsertTailList(&DeviceList, &Node->Entry);
300 return Node;
301}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define InsertTailList(ListHead, Entry)

Referenced by DosCreateDeviceEx(), DosGetDriverNode(), and DosLoadDriver().

◆ DosDeleteDevice()

VOID DosDeleteDevice ( PDOS_DEVICE_NODE  DeviceNode)

Definition at line 419 of file device.c.

420{
422
423 ASSERT(LOWORD(DeviceNode->Driver) == 0);
425
427 RtlFreeHeap(RtlGetProcessHeap(), 0, DeviceNode);
428}
@ DeviceNode
Definition: Node.h:9
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ASSERT(a)
Definition: mode.c:44
static VOID DosRemoveDriver(DWORD Driver)
Definition: device.c:256

Referenced by ConDrvCleanup(), EmsDrvCleanup(), and XmsCleanup().

◆ DosDriverDispatchClose()

static WORD NTAPI DosDriverDispatchClose ( PDOS_DEVICE_NODE  DeviceNode)
static

Definition at line 206 of file device.c.

207{
209}
static WORD NTAPI DosDriverGenericRequest(PDOS_DEVICE_NODE DeviceNode, BYTE CommandCode)
Definition: device.c:126

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchFlushInput()

static WORD NTAPI DosDriverDispatchFlushInput ( PDOS_DEVICE_NODE  DeviceNode)
static

Definition at line 172 of file device.c.

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchFlushOutput()

static WORD NTAPI DosDriverDispatchFlushOutput ( PDOS_DEVICE_NODE  DeviceNode)
static

Definition at line 196 of file device.c.

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchInputStatus()

static WORD NTAPI DosDriverDispatchInputStatus ( PDOS_DEVICE_NODE  DeviceNode)
static

Definition at line 167 of file device.c.

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchIoctlRead()

static WORD NTAPI DosDriverDispatchIoctlRead ( PDOS_DEVICE_NODE  DeviceNode,
DWORD  Buffer,
PWORD  Length 
)
static

Definition at line 139 of file device.c.

142{
144}
Definition: bufpool.h:45
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static WORD NTAPI DosDriverReadInternal(PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length, BOOLEAN IoControl)
Definition: device.c:88

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchIoctlWrite()

static WORD NTAPI DosDriverDispatchIoctlWrite ( PDOS_DEVICE_NODE  DeviceNode,
DWORD  Buffer,
PWORD  Length 
)
static

Definition at line 177 of file device.c.

180{
182}
static WORD NTAPI DosDriverWriteInternal(PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length, BOOLEAN IoControl)
Definition: device.c:107

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchOpen()

static WORD NTAPI DosDriverDispatchOpen ( PDOS_DEVICE_NODE  DeviceNode)
static

Definition at line 201 of file device.c.

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchOutputStatus()

static WORD NTAPI DosDriverDispatchOutputStatus ( PDOS_DEVICE_NODE  DeviceNode)
static

Definition at line 191 of file device.c.

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchOutputUntilBusy()

static WORD NTAPI DosDriverDispatchOutputUntilBusy ( PDOS_DEVICE_NODE  DeviceNode,
DWORD  Buffer,
PWORD  Length 
)
static

Definition at line 211 of file device.c.

214{
216
217 Request.Header.RequestLength = sizeof(DOS_OUTPUT_BUSY_REQUEST);
218 Request.Header.CommandCode = DOS_DEVCMD_OUTPUT_BUSY;
219 Request.BufferPointer = Buffer;
220 Request.Length = *Length;
221
222 DosCallDriver(DeviceNode->Driver, &Request.Header);
223
224 *Length = Request.Length;
225 return Request.Header.Status;
226}
static VOID DosCallDriver(DWORD Driver, PDOS_REQUEST_HEADER Request)
Definition: device.c:49
struct _DOS_OUTPUT_BUSY_REQUEST DOS_OUTPUT_BUSY_REQUEST

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchPeek()

static WORD NTAPI DosDriverDispatchPeek ( PDOS_DEVICE_NODE  DeviceNode,
PBYTE  Character 
)
static

Definition at line 153 of file device.c.

155{
157
158 Request.Header.RequestLength = sizeof(DOS_PEEK_REQUEST);
159 Request.Header.CommandCode = DOS_DEVCMD_PEEK;
160
161 DosCallDriver(DeviceNode->Driver, &Request.Header);
162
163 *Character = Request.Character;
164 return Request.Header.Status;
165}
struct _DOS_PEEK_REQUEST DOS_PEEK_REQUEST

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchRead()

static WORD NTAPI DosDriverDispatchRead ( PDOS_DEVICE_NODE  DeviceNode,
DWORD  Buffer,
PWORD  Length 
)
static

Definition at line 146 of file device.c.

149{
151}
#define FALSE
Definition: types.h:117

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverDispatchWrite()

static WORD NTAPI DosDriverDispatchWrite ( PDOS_DEVICE_NODE  DeviceNode,
DWORD  Buffer,
PWORD  Length 
)
static

Definition at line 184 of file device.c.

Referenced by DosGetDriverNode(), and DosLoadDriver().

◆ DosDriverGenericRequest()

static WORD NTAPI DosDriverGenericRequest ( PDOS_DEVICE_NODE  DeviceNode,
BYTE  CommandCode 
)
inlinestatic

Definition at line 126 of file device.c.

128{
130
131 Request.RequestLength = sizeof(DOS_REQUEST_HEADER);
132 Request.CommandCode = CommandCode;
133
135
136 return Request.Status;
137}
struct _DOS_REQUEST_HEADER DOS_REQUEST_HEADER

Referenced by DosDriverDispatchClose(), DosDriverDispatchFlushInput(), DosDriverDispatchFlushOutput(), DosDriverDispatchInputStatus(), DosDriverDispatchOpen(), and DosDriverDispatchOutputStatus().

◆ DosDriverReadInternal()

static WORD NTAPI DosDriverReadInternal ( PDOS_DEVICE_NODE  DeviceNode,
DWORD  Buffer,
PWORD  Length,
BOOLEAN  IoControl 
)
inlinestatic

Definition at line 88 of file device.c.

92{
94
95 Request.Header.RequestLength = IoControl ? sizeof(DOS_IOCTL_RW_REQUEST)
96 : sizeof(DOS_RW_REQUEST);
97 Request.Header.CommandCode = IoControl ? DOS_DEVCMD_IOCTL_READ : DOS_DEVCMD_READ;
98 Request.BufferPointer = Buffer;
99 Request.Length = *Length;
100
101 DosCallDriver(DeviceNode->Driver, &Request.Header);
102
103 *Length = Request.Length;
104 return Request.Header.Status;
105}
struct _DOS_IOCTL_RW_REQUEST DOS_IOCTL_RW_REQUEST

Referenced by DosDriverDispatchIoctlRead(), and DosDriverDispatchRead().

◆ DosDriverWriteInternal()

static WORD NTAPI DosDriverWriteInternal ( PDOS_DEVICE_NODE  DeviceNode,
DWORD  Buffer,
PWORD  Length,
BOOLEAN  IoControl 
)
inlinestatic

Definition at line 107 of file device.c.

111{
113
114 Request.Header.RequestLength = IoControl ? sizeof(DOS_IOCTL_RW_REQUEST)
115 : sizeof(DOS_RW_REQUEST);
116 Request.Header.CommandCode = IoControl ? DOS_DEVCMD_IOCTL_WRITE : DOS_DEVCMD_WRITE;
117 Request.BufferPointer = Buffer;
118 Request.Length = *Length;
119
120 DosCallDriver(DeviceNode->Driver, &Request.Header);
121
122 *Length = Request.Length;
123 return Request.Header.Status;
124}

Referenced by DosDriverDispatchIoctlWrite(), and DosDriverDispatchWrite().

◆ DosGetDevice()

PDOS_DEVICE_NODE DosGetDevice ( LPCSTR  DeviceName)

Definition at line 342 of file device.c.

343{
345 ANSI_STRING DeviceNameString;
346
347 RtlInitAnsiString(&DeviceNameString, DeviceName);
348
349 while (LOWORD(CurrentDriver) != 0xFFFF)
350 {
351 PDOS_DEVICE_NODE Node = DosGetDriverNode(CurrentDriver);
352 PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(CurrentDriver);
353
354 if (RtlEqualString(&Node->Name, &DeviceNameString, TRUE)) return Node;
355 CurrentDriver = DriverHeader->Link;
356 }
357
358 return NULL;
359}
NTSYSAPI BOOLEAN NTAPI RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
PDOS_DEVICE_NODE DosGetDriverNode(DWORD Driver)
Definition: device.c:305

Referenced by DosCreateFile(), DosCreateFileEx(), and DosOpenFile().

◆ DosGetDriverNode()

PDOS_DEVICE_NODE DosGetDriverNode ( DWORD  Driver)

Definition at line 305 of file device.c.

306{
309
310 for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink)
311 {
313 if (Node->Driver == Driver) break;
314 }
315
316 if (i == &DeviceList)
317 {
318 DPRINT1("The driver at %04X:%04X has no associated device node. "
319 "Installing automagically.\n",
320 HIWORD(Driver),
321 LOWORD(Driver));
322
323 /* Create the device node */
325 Node->IoctlReadRoutine = DosDriverDispatchIoctlRead;
326 Node->ReadRoutine = DosDriverDispatchRead;
327 Node->PeekRoutine = DosDriverDispatchPeek;
328 Node->InputStatusRoutine = DosDriverDispatchInputStatus;
329 Node->FlushInputRoutine = DosDriverDispatchFlushInput;
330 Node->IoctlWriteRoutine = DosDriverDispatchIoctlWrite;
331 Node->WriteRoutine = DosDriverDispatchWrite;
332 Node->OutputStatusRoutine = DosDriverDispatchOutputStatus;
333 Node->FlushOutputRoutine = DosDriverDispatchFlushOutput;
334 Node->OpenRoutine = DosDriverDispatchOpen;
335 Node->CloseRoutine = DosDriverDispatchClose;
336 Node->OutputUntilBusyRoutine = DosDriverDispatchOutputUntilBusy;
337 }
338
339 return Node;
340}
static WORD NTAPI DosDriverDispatchPeek(PDOS_DEVICE_NODE DeviceNode, PBYTE Character)
Definition: device.c:153
static WORD NTAPI DosDriverDispatchIoctlWrite(PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
Definition: device.c:177
static WORD NTAPI DosDriverDispatchFlushOutput(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:196
static WORD NTAPI DosDriverDispatchIoctlRead(PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
Definition: device.c:139
static WORD NTAPI DosDriverDispatchOutputStatus(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:191
static WORD NTAPI DosDriverDispatchInputStatus(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:167
static WORD NTAPI DosDriverDispatchFlushInput(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:172
static WORD NTAPI DosDriverDispatchWrite(PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
Definition: device.c:184
static WORD NTAPI DosDriverDispatchClose(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:206
static WORD NTAPI DosDriverDispatchRead(PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
Definition: device.c:146
static WORD NTAPI DosDriverDispatchOutputUntilBusy(PDOS_DEVICE_NODE DeviceNode, DWORD Buffer, PWORD Length)
Definition: device.c:211
static WORD NTAPI DosDriverDispatchOpen(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:201

Referenced by DosCheckInput(), DosCloseHandle(), DosCopyHandleTable(), DosDeviceIoControl(), DosFlushFileBuffers(), DosGetDevice(), DosReadFile(), DosReadLineBuffered(), and DosWriteFile().

◆ DosLoadDriver()

DWORD DosLoadDriver ( LPCSTR  DriverFile)

Definition at line 571 of file device.c.

572{
577 PDOS_DRIVER DriverHeader;
578 WORD Segment = 0;
580 DWORD DriversLoaded = 0;
583
584 /* Open a handle to the driver file */
585 FileHandle = CreateFileA(DriverFile,
588 NULL,
591 NULL);
593 {
595 goto Cleanup;
596 }
597
598 /* Get the file size */
600
601 /* Allocate DOS memory for the driver */
603 if (Segment == 0)
604 {
606 goto Cleanup;
607 }
608
609 /* Create a mapping object for the file */
610 FileMapping = CreateFileMapping(FileHandle,
611 NULL,
613 0,
614 0,
615 NULL);
616 if (FileMapping == NULL)
617 {
619 goto Cleanup;
620 }
621
622 /* Map the file into memory */
623 Address = (LPBYTE)MapViewOfFile(FileMapping, FILE_MAP_READ, 0, 0, 0);
624 if (Address == NULL)
625 {
627 goto Cleanup;
628 }
629
630 /* Copy the entire file to the DOS memory */
631 Driver = MAKELONG(0, Segment);
632 DriverHeader = (PDOS_DRIVER)FAR_POINTER(Driver);
633 RtlCopyMemory(DriverHeader, Address, FileSize);
634
635 /* Loop through all the drivers in this file */
636 while (TRUE)
637 {
638 if (!(DriverHeader->DeviceAttributes & DOS_DEVATTR_CHARACTER))
639 {
640 DPRINT1("Error loading driver at %04X:%04X: "
641 "Block device drivers are not supported.\n",
642 HIWORD(Driver),
643 LOWORD(Driver));
644 goto Next;
645 }
646
647 /* Send the driver an init request */
648 RtlZeroMemory(&Request, sizeof(Request));
649 Request.Header.RequestLength = sizeof(DOS_INIT_REQUEST);
650 Request.Header.CommandCode = DOS_DEVCMD_INIT;
651 // TODO: Set Request.DeviceString to the appropriate line in CONFIG.NT!
652 DosCallDriver(Driver, &Request.Header);
653
654 if (Request.Header.Status & DOS_DEVSTAT_ERROR)
655 {
656 DPRINT1("Error loading driver at %04X:%04X: "
657 "Initialization routine returned error %u.\n",
658 HIWORD(Driver),
659 LOWORD(Driver),
660 Request.Header.Status & 0x7F);
661 goto Next;
662 }
663
664 /* Create the device node */
666 DeviceNode->IoctlReadRoutine = DosDriverDispatchIoctlRead;
667 DeviceNode->ReadRoutine = DosDriverDispatchRead;
668 DeviceNode->PeekRoutine = DosDriverDispatchPeek;
669 DeviceNode->InputStatusRoutine = DosDriverDispatchInputStatus;
670 DeviceNode->FlushInputRoutine = DosDriverDispatchFlushInput;
671 DeviceNode->IoctlWriteRoutine = DosDriverDispatchIoctlWrite;
672 DeviceNode->WriteRoutine = DosDriverDispatchWrite;
673 DeviceNode->OutputStatusRoutine = DosDriverDispatchOutputStatus;
674 DeviceNode->FlushOutputRoutine = DosDriverDispatchFlushOutput;
675 DeviceNode->OpenRoutine = DosDriverDispatchOpen;
676 DeviceNode->CloseRoutine = DosDriverDispatchClose;
677 DeviceNode->OutputUntilBusyRoutine = DosDriverDispatchOutputUntilBusy;
678
680 DriversLoaded++;
681
682Next:
683 if (LOWORD(DriverHeader->Link) == 0xFFFF) break;
684 Driver = DriverHeader->Link;
685 DriverHeader = (PDOS_DRIVER)FAR_POINTER(Driver);
686 }
687
688 DPRINT1("%u drivers loaded from %s.\n", DriversLoaded, DriverFile);
689
690Cleanup:
691 if (Result != ERROR_SUCCESS)
692 {
693 /* It was not successful, cleanup the DOS memory */
695 }
696
697 /* Unmap the file */
699
700 /* Close the file mapping object */
701 if (FileMapping != NULL) CloseHandle(FileMapping);
702
703 /* Close the file handle */
705
706 return Result;
707}
#define ERROR_SUCCESS
Definition: deptool.c:10
#define CloseHandle
Definition: compat.h:739
#define PAGE_READONLY
Definition: compat.h:138
#define UnmapViewOfFile
Definition: compat.h:746
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define FILE_MAP_READ
Definition: compat.h:776
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define MapViewOfFile
Definition: compat.h:745
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
static const WCHAR Cleanup[]
Definition: register.c:80
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
static WCHAR Address[46]
Definition: ping.c:68
WORD LastErrorCode
Definition: dos.h:160
#define DOS_DEVCMD_INIT
Definition: device.h:31
struct _DOS_INIT_REQUEST DOS_INIT_REQUEST
#define DOS_DEVSTAT_ERROR
Definition: device.h:51
unsigned char * LPBYTE
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CreateFileMapping
Definition: winbase.h:3750
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

◆ DosRemoveDriver()

static VOID DosRemoveDriver ( DWORD  Driver)
static

Definition at line 256 of file device.c.

257{
259
260 while (LOWORD(CurrentDriver) != 0xFFFF)
261 {
262 PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(CurrentDriver);
263
264 if (DriverHeader->Link == Driver)
265 {
266 /* Remove it from the list */
267 DriverHeader->Link = ((PDOS_DRIVER)FAR_POINTER(DriverHeader->Link))->Link;
268 return;
269 }
270
271 CurrentDriver = DriverHeader->Link;
272 }
273}
static int Link(const char **args)
Definition: vfdcmd.c:2414

Referenced by DosDeleteDevice().

Variable Documentation

◆ DeviceList

LIST_ENTRY DeviceList = { &DeviceList, &DeviceList }
static

Definition at line 44 of file device.c.

Referenced by DeviceInterruptBop(), DosCreateDeviceNode(), and DosGetDriverNode().

◆ DeviceRequest

PDOS_REQUEST_HEADER DeviceRequest
static

Definition at line 45 of file device.c.

Referenced by DeviceInterruptBop(), and DeviceStrategyBop().

◆ InterruptRoutine

const BYTE InterruptRoutine[]
static
Initial value:
= {
0xCB
}
#define EMULATOR_BOP
Definition: bop.h:16
#define BOP_DOS
Definition: dem.h:26
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define BOP_DRV_INTERRUPT
Definition: device.h:19

Definition at line 34 of file device.c.

Referenced by DosCreateDeviceEx().

◆ StrategyRoutine

const BYTE StrategyRoutine[]
static
Initial value:
= {
0xCB
}
#define BOP_DRV_STRATEGY
Definition: device.h:18

Definition at line 26 of file device.c.

Referenced by DosCreateDeviceEx().