1 /*
2  * COPYRIGHT:       GPLv2+ - See COPYING in the top level directory
3  * PROJECT:         ReactOS Virtual DOS Machine
4  * FILE:            subsystems/mvdm/ntvdm/dos/dos32krnl/device.h
5  * PURPOSE:         DOS Device Support
6  * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7  */
8 
9 #ifndef _DEVICE_H_
10 #define _DEVICE_H_
11 
12 /* DEFINITIONS ****************************************************************/
13 
14 #define MAX_DEVICE_NAME 8
15 #define DEVICE_CODE_SIZE 10
16 #define DEVICE_PRIVATE_AREA(Driver) (Driver + sizeof(DOS_DRIVER) + DEVICE_CODE_SIZE)
17 
18 #define BOP_DRV_STRATEGY  0x42
19 #define BOP_DRV_INTERRUPT 0x43
20 
21 #define DOS_DEVATTR_STDIN       (1 << 0)
22 #define DOS_DEVATTR_STDOUT      (1 << 1)
23 #define DOS_DEVATTR_NUL         (1 << 2)
24 #define DOS_DEVATTR_CLOCK       (1 << 3)
25 #define DOS_DEVATTR_CON         (1 << 4)
26 #define DOS_DEVATTR_OPENCLOSE   (1 << 11)
27 #define DOS_DEVATTR_SPECIAL     (1 << 13)
28 #define DOS_DEVATTR_IOCTL       (1 << 14)
29 #define DOS_DEVATTR_CHARACTER   (1 << 15)
30 
31 #define DOS_DEVCMD_INIT         0
32 #define DOS_DEVCMD_MEDIACHK     1
33 #define DOS_DEVCMD_BUILDBPB     2
34 #define DOS_DEVCMD_IOCTL_READ   3
35 #define DOS_DEVCMD_READ         4
36 #define DOS_DEVCMD_PEEK         5
37 #define DOS_DEVCMD_INSTAT       6
38 #define DOS_DEVCMD_FLUSH_INPUT  7
39 #define DOS_DEVCMD_WRITE        8
40 #define DOS_DEVCMD_WRITE_VERIFY 9
41 #define DOS_DEVCMD_OUTSTAT      10
42 #define DOS_DEVCMD_FLUSH_OUTPUT 11
43 #define DOS_DEVCMD_IOCTL_WRITE  12
44 #define DOS_DEVCMD_OPEN         13
45 #define DOS_DEVCMD_CLOSE        14
46 #define DOS_DEVCMD_REMOVABLE    15
47 #define DOS_DEVCMD_OUTPUT_BUSY  16
48 
49 #define DOS_DEVSTAT_DONE    (1 << 8)
50 #define DOS_DEVSTAT_BUSY    (1 << 9)
51 #define DOS_DEVSTAT_ERROR   (1 << 15)
52 
53 #define DOS_DEVERR_WRITE_PROTECT    0
54 #define DOS_DEVERR_UNKNOWN_UNIT     1
55 #define DOS_DEVERR_NOT_READY        2
56 #define DOS_DEVERR_UNKNOWN_COMMAND  3
57 #define DOS_DEVERR_BAD_DATA_CRC     4
58 #define DOS_DEVERR_BAD_REQUEST      5
59 #define DOS_DEVERR_INVALID_SEEK     6
60 #define DOS_DEVERR_UNKNOWN_MEDIUM   7
61 #define DOS_DEVERR_BAD_BLOCK        8
62 #define DOS_DEVERR_OUT_OF_PAPER     9
63 #define DOS_DEVERR_WRITE_FAULT      10
64 #define DOS_DEVERR_READ_FAULT       11
65 #define DOS_DEVERR_GENERAL          12
66 #define DOS_DEVERR_BAD_MEDIA_CHANGE 15
67 
68 typedef struct _DOS_DEVICE_NODE DOS_DEVICE_NODE, *PDOS_DEVICE_NODE;
69 
70 typedef WORD (NTAPI *PDOS_DEVICE_GENERIC_ROUTINE)(PDOS_DEVICE_NODE DeviceNode);
71 
72 typedef WORD (NTAPI *PDOS_DEVICE_IO_ROUTINE)
73 (
74     PDOS_DEVICE_NODE DeviceNode,
75     DWORD Buffer,
76     PWORD Length
77 );
78 
79 typedef WORD (NTAPI *PDOS_DEVICE_PEEK_ROUTINE)
80 (
81     PDOS_DEVICE_NODE DeviceNode,
82     PBYTE Character
83 );
84 
85 struct _DOS_DEVICE_NODE
86 {
87     LIST_ENTRY Entry;
88     DWORD Driver;
89     WORD DeviceAttributes;
90     ANSI_STRING Name;
91     CHAR NameBuffer[MAX_DEVICE_NAME];
92     PDOS_DEVICE_IO_ROUTINE IoctlReadRoutine;
93     PDOS_DEVICE_IO_ROUTINE ReadRoutine;
94     PDOS_DEVICE_PEEK_ROUTINE PeekRoutine;
95     PDOS_DEVICE_GENERIC_ROUTINE InputStatusRoutine;
96     PDOS_DEVICE_GENERIC_ROUTINE FlushInputRoutine;
97     PDOS_DEVICE_IO_ROUTINE IoctlWriteRoutine;
98     PDOS_DEVICE_IO_ROUTINE WriteRoutine;
99     PDOS_DEVICE_GENERIC_ROUTINE OutputStatusRoutine;
100     PDOS_DEVICE_GENERIC_ROUTINE FlushOutputRoutine;
101     PDOS_DEVICE_GENERIC_ROUTINE OpenRoutine;
102     PDOS_DEVICE_GENERIC_ROUTINE CloseRoutine;
103     PDOS_DEVICE_IO_ROUTINE OutputUntilBusyRoutine;
104 };
105 
106 #pragma pack(push, 1)
107 
108 typedef struct _DOS_DRIVER
109 {
110     DWORD Link;
111     WORD  DeviceAttributes;
112     WORD  StrategyRoutine;
113     WORD  InterruptRoutine;
114 
115     union
116     {
117         CHAR DeviceName[MAX_DEVICE_NAME]; // for character devices
118 
119         struct // for block devices
120         {
121             BYTE UnitCount;
122             BYTE Reserved[MAX_DEVICE_NAME - 1];
123         };
124     };
125 } DOS_DRIVER, *PDOS_DRIVER;
126 C_ASSERT(sizeof(DOS_DRIVER) == 0x12);
127 
128 typedef struct _DOS_REQUEST_HEADER
129 {
130     IN  BYTE RequestLength;
131     IN  BYTE UnitNumber OPTIONAL;
132     IN  BYTE CommandCode;
133     OUT WORD Status;
134 
135     BYTE Reserved[8];
136 } DOS_REQUEST_HEADER, *PDOS_REQUEST_HEADER;
137 
138 typedef struct _DOS_INIT_REQUEST
139 {
140     DOS_REQUEST_HEADER Header;
141 
142     OUT BYTE  UnitsInitialized;
143     OUT DWORD ReturnBreakAddress;
144 
145     union
146     {
147         IN  DWORD DeviceString; // for character devices
148 
149         struct // for block devices
150         {
151             IN  BYTE FirstDriveLetter;
152             OUT DWORD BpbPointer;
153         };
154     };
155 
156 } DOS_INIT_REQUEST, *PDOS_INIT_REQUEST;
157 
158 typedef struct _DOS_IOCTL_RW_REQUEST
159 {
160     DOS_REQUEST_HEADER Header;
161 
162     IN     BYTE  MediaDescriptorByte OPTIONAL;
163     IN     DWORD BufferPointer;
164     IN OUT WORD  Length;
165     IN     WORD  StartingBlock OPTIONAL;
166 } DOS_IOCTL_RW_REQUEST, *PDOS_IOCTL_RW_REQUEST;
167 
168 typedef struct _DOS_RW_REQUEST
169 {
170     DOS_REQUEST_HEADER Header;
171 
172     IN     BYTE  MediaDescriptorByte OPTIONAL;
173     IN     DWORD BufferPointer;
174     IN OUT WORD  Length;
175     IN     WORD  StartingBlock  OPTIONAL;
176     OUT    DWORD VolumeLabelPtr OPTIONAL;
177 } DOS_RW_REQUEST, *PDOS_RW_REQUEST;
178 
179 typedef struct _DOS_PEEK_REQUEST
180 {
181     DOS_REQUEST_HEADER Header;
182     OUT BYTE Character;
183 } DOS_PEEK_REQUEST, *PDOS_PEEK_REQUEST;
184 
185 typedef struct _DOS_OUTPUT_BUSY_REQUEST
186 {
187     DOS_REQUEST_HEADER Header;
188 
189     IN     DWORD BufferPointer;
190     IN OUT WORD  Length;
191 } DOS_OUTPUT_BUSY_REQUEST, *PDOS_OUTPUT_BUSY_REQUEST;
192 
193 #pragma pack(pop)
194 
195 /* FUNCTIONS ******************************************************************/
196 
197 PDOS_DEVICE_NODE DosGetDriverNode(DWORD Driver);
198 PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName);
199 PDOS_DEVICE_NODE DosCreateDevice(WORD Attributes, PCHAR DeviceName);
200 PDOS_DEVICE_NODE DosCreateDeviceEx
201 (
202     WORD Attributes,
203     PCHAR DeviceName,
204     WORD PrivateDataSize
205 );
206 VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode);
207 VOID DeviceStrategyBop(VOID);
208 VOID DeviceInterruptBop(VOID);
209 DWORD DosLoadDriver(LPCSTR DriverFile);
210 
211 #endif /* _DEVICE_H_ */
212