Rev 2644 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2644 | Rev 5044 | ||
---|---|---|---|
Line 23... | Line 23... | ||
23 | ERROR_INVALID_ID equ 2 ; .DiskId must be from 0 to 9 |
23 | ERROR_INVALID_ID equ 2 ; .DiskId must be from 0 to 9 |
24 | ERROR_SIZE_TOO_LARGE equ 3 ; .DiskSize is too large |
24 | ERROR_SIZE_TOO_LARGE equ 3 ; .DiskSize is too large |
25 | ERROR_SIZE_TOO_SMALL equ 4 ; .DiskSize is too small |
25 | ERROR_SIZE_TOO_SMALL equ 4 ; .DiskSize is too small |
26 | ERROR_NO_MEMORY equ 5 ; memory allocation failed |
26 | ERROR_NO_MEMORY equ 5 ; memory allocation failed |
Line -... | Line 27... | ||
- | 27 | ||
Line 27... | Line 28... | ||
27 | 28 | include '../struct.inc' |
|
28 | 29 | ||
29 | API_VERSION equ 1 |
30 | API_VERSION equ 1 |
30 | ; Input structures: |
- | |
31 | struc add_disk_struc |
31 | ; Input structures: |
32 | { |
32 | struct add_disk_struc |
33 | .DiskSize dd ? ; disk size in sectors, 1 sector = 512 bytes |
33 | DiskSize dd ? ; disk size in sectors, 1 sector = 512 bytes |
34 | ; Note: .DiskSize is the full size, including FAT service data. |
34 | ; Note: DiskSize is the full size, including FAT service data. |
35 | ; Size for useful data is slightly less than this number. |
- | |
36 | .DiskId db ? ; from 0 to 9 |
- | |
37 | .sizeof: |
- | |
38 | } |
- | |
39 | virtual at 0 |
35 | ; Size for useful data is slightly less than this number. |
40 | add_disk_struc add_disk_struc |
36 | DiskId db ? ; from 0 to 9 |
41 | end virtual |
- | |
42 | struc del_disk_struc |
37 | ends |
43 | { |
- | |
44 | .DiskId db ? ; from 0 to 9 |
- | |
45 | .sizeof: |
- | |
46 | } |
- | |
47 | virtual at 0 |
38 | struct del_disk_struc |
Line 48... | Line 39... | ||
48 | del_disk_struc del_disk_struc |
39 | DiskId db ? ; from 0 to 9 |
Line 49... | Line 40... | ||
49 | end virtual |
40 | ends |
50 | 41 | ||
Line 51... | Line 42... | ||
51 | max_num_disks equ 10 |
42 | max_num_disks equ 10 |
52 | - | ||
53 | ; standard driver stuff |
- | |
Line -... | Line 43... | ||
- | 43 | ||
54 | format MS COFF |
44 | ; standard driver stuff; version of driver model = 5 |
55 | 45 | format PE DLL native 0.05 |
|
56 | DEBUG equ 0 |
- | |
57 | include 'proc32.inc' |
46 | |
58 | include 'imports.inc' |
- | |
59 | - | ||
60 | public START |
- | |
61 | public version |
47 | DEBUG equ 0 |
62 | 48 | ||
63 | struc IOCTL |
- | |
64 | { |
- | |
65 | .handle dd ? |
- | |
66 | .io_code dd ? |
- | |
67 | .input dd ? |
- | |
68 | .inp_size dd ? |
- | |
69 | .output dd ? |
- | |
70 | .out_size dd ? |
- | |
71 | } |
49 | section '.flat' code readable writable executable |
72 | 50 | data fixups |
|
73 | virtual at 0 |
51 | end data |
74 | IOCTL IOCTL |
52 | entry START |
75 | end virtual |
53 | include '../proc32.inc' |
76 | 54 | include '../peimport.inc' |
|
77 | section '.flat' code readable align 16 |
55 | include '../macros.inc' |
78 | ; the start procedure (see the description above) |
56 | ; the start procedure (see the description above) |
79 | proc START |
57 | proc START |
80 | ; This procedure is called in two situations: |
58 | ; This procedure is called in two situations: |
81 | ; when the driver is loading and when the system is shutting down. |
59 | ; when the driver is loading and when the system is shutting down. |
82 | ; 1. Check that the driver is loading; do nothing unless so. |
60 | ; 1. Check that the driver is loading; do nothing unless so. |
83 | xor eax, eax ; set return value in case we will do nothing |
61 | xor eax, eax ; set return value in case we will do nothing |
84 | cmp dword [esp+4], 1 |
62 | cmp dword [esp+4], 1 |
85 | jne .nothing |
63 | jne .nothing |
Line 86... | Line 64... | ||
86 | ; 2. Register the driver in the system. |
64 | ; 2. Register the driver in the system. |
87 | stdcall RegService, my_service, service_proc |
65 | invoke RegService, my_service, service_proc |
88 | ; 3. Return the value returned by RegService back to the system. |
66 | ; 3. Return the value returned by RegService back to the system. |
Line 120... | Line 98... | ||
120 | jmp .return |
98 | jmp .return |
121 | .no.srv_getversion: |
99 | .no.srv_getversion: |
122 | dec ecx ; check for DEV_ADD_DISK |
100 | dec ecx ; check for DEV_ADD_DISK |
123 | jnz .no.dev_add_disk |
101 | jnz .no.dev_add_disk |
124 | ; 5. This is DEV_ADD_DISK request, input is add_disk_struc, output is 1 byte |
102 | ; 5. This is DEV_ADD_DISK request, input is add_disk_struc, output is 1 byte |
125 | ; 5a. Input size must be exactly add_disk_struc.sizeof bytes. |
103 | ; 5a. Input size must be exactly sizeof.add_disk_struc bytes. |
126 | cmp [edx+IOCTL.inp_size], add_disk_struc.sizeof |
104 | cmp [edx+IOCTL.inp_size], sizeof.add_disk_struc |
127 | jnz .return |
105 | jnz .return |
128 | ; 5b. Load input parameters and call the worker procedure. |
106 | ; 5b. Load input parameters and call the worker procedure. |
129 | mov eax, [edx+IOCTL.input] |
107 | mov eax, [edx+IOCTL.input] |
130 | movzx ebx, [eax+add_disk_struc.DiskId] |
108 | movzx ebx, [eax+add_disk_struc.DiskId] |
131 | mov esi, [eax+add_disk_struc.DiskSize] |
109 | mov esi, [eax+add_disk_struc.DiskSize] |
Line 134... | Line 112... | ||
134 | jmp .return |
112 | jmp .return |
135 | .no.dev_add_disk: |
113 | .no.dev_add_disk: |
136 | dec ecx ; check for DEV_DEL_DISK |
114 | dec ecx ; check for DEV_DEL_DISK |
137 | jnz .return |
115 | jnz .return |
138 | ; 6. This is DEV_DEL_DISK request, input is del_disk_struc |
116 | ; 6. This is DEV_DEL_DISK request, input is del_disk_struc |
139 | ; 6a. Input size must be exactly del_disk_struc.sizeof bytes. |
117 | ; 6a. Input size must be exactly sizeof.del_disk_struc bytes. |
140 | cmp [edx+IOCTL.inp_size], del_disk_struc.sizeof |
118 | cmp [edx+IOCTL.inp_size], sizeof.del_disk_struc |
141 | jnz .return |
119 | jnz .return |
142 | ; 6b. Load input parameters and call the worker procedure. |
120 | ; 6b. Load input parameters and call the worker procedure. |
143 | mov eax, [edx+IOCTL.input] |
121 | mov eax, [edx+IOCTL.input] |
144 | movzx ebx, [eax+del_disk_struc.DiskId] |
122 | movzx ebx, [eax+del_disk_struc.DiskId] |
145 | call del_disk |
123 | call del_disk |
Line 177... | Line 155... | ||
177 | jb .return |
155 | jb .return |
178 | ; 3. Allocate memory for the disk, store the pointer in edi. |
156 | ; 3. Allocate memory for the disk, store the pointer in edi. |
179 | ; If failed, return the corresponding error code. |
157 | ; If failed, return the corresponding error code. |
180 | mov eax, esi |
158 | mov eax, esi |
181 | shl eax, 9 |
159 | shl eax, 9 |
182 | stdcall KernelAlloc, eax |
160 | invoke KernelAlloc, eax |
183 | mov edi, eax |
161 | mov edi, eax |
184 | test eax, eax |
162 | test eax, eax |
185 | mov al, ERROR_NO_MEMORY |
163 | mov al, ERROR_NO_MEMORY |
186 | jz .return |
164 | jz .return |
187 | ; 4. Store the pointer and the size in the global variables. |
165 | ; 4. Store the pointer and the size in the global variables. |
Line 191... | Line 169... | ||
191 | ; Play extra safe and store new value only if old value is zero. |
169 | ; Play extra safe and store new value only if old value is zero. |
192 | xor eax, eax |
170 | xor eax, eax |
193 | lock cmpxchg [disk_pointers+ebx*4], edi |
171 | lock cmpxchg [disk_pointers+ebx*4], edi |
194 | jz @f |
172 | jz @f |
195 | ; Otherwise, free the allocated memory and return the corresponding error code. |
173 | ; Otherwise, free the allocated memory and return the corresponding error code. |
196 | stdcall KernelFree, edi |
174 | invoke KernelFree, edi |
197 | mov al, ERROR_INVALID_ID |
175 | mov al, ERROR_INVALID_ID |
198 | jmp .return |
176 | jmp .return |
199 | @@: |
177 | @@: |
200 | mov [disk_sizes+ebx*4], esi |
178 | mov [disk_sizes+ebx*4], esi |
201 | ; 5. Call the worker procedure for formatting this disk. |
179 | ; 5. Call the worker procedure for formatting this disk. |
Line 207... | Line 185... | ||
207 | push 'tmp' |
185 | push 'tmp' |
208 | mov eax, esp ; eax points to 'tmp' + zero byte + zero dword |
186 | mov eax, esp ; eax points to 'tmp' + zero byte + zero dword |
209 | lea ecx, [ebx+'0'] ; ecx = digit |
187 | lea ecx, [ebx+'0'] ; ecx = digit |
210 | mov [eax+3], cl ; eax points to 'tmp#' + zero dword |
188 | mov [eax+3], cl ; eax points to 'tmp#' + zero dword |
211 | ; 6b. Call the kernel API. Use disk id as 'userdata' parameter for callbacks. |
189 | ; 6b. Call the kernel API. Use disk id as 'userdata' parameter for callbacks. |
212 | stdcall DiskAdd, disk_functions, eax, ebx, 0 |
190 | invoke DiskAdd, disk_functions, eax, ebx, 0 |
213 | ; 6c. Restore the stack after 6a. |
191 | ; 6c. Restore the stack after 6a. |
214 | pop ecx ecx |
192 | pop ecx ecx |
215 | ; 6c. Check the result. If DiskAdd has failed, cleanup and return |
193 | ; 6c. Check the result. If DiskAdd has failed, cleanup and return |
216 | ; ERROR_NO_MEMORY, this is the most probable or even the only reason to fail. |
194 | ; ERROR_NO_MEMORY, this is the most probable or even the only reason to fail. |
217 | test eax, eax |
195 | test eax, eax |
218 | jnz @f |
196 | jnz @f |
219 | mov [disk_sizes+ebx*4], 0 |
197 | mov [disk_sizes+ebx*4], 0 |
220 | mov [disk_pointers+ebx*4], 0 |
198 | mov [disk_pointers+ebx*4], 0 |
221 | stdcall KernelFree, edi |
199 | invoke KernelFree, edi |
222 | mov al, ERROR_NO_MEMORY |
200 | mov al, ERROR_NO_MEMORY |
223 | jmp .return |
201 | jmp .return |
224 | @@: |
202 | @@: |
225 | push eax |
203 | push eax |
226 | ; 6d. Notify the kernel that media is inserted. |
204 | ; 6d. Notify the kernel that media is inserted. |
227 | stdcall DiskMediaChanged, eax, 1 |
205 | invoke DiskMediaChanged, eax, 1 |
228 | ; 6e. Disk is fully configured; store its handle in the global variable |
206 | ; 6e. Disk is fully configured; store its handle in the global variable |
229 | ; and return success. |
207 | ; and return success. |
230 | pop [disk_handles+ebx*4] |
208 | pop [disk_handles+ebx*4] |
231 | xor eax, eax |
209 | xor eax, eax |
232 | ; 7. Return. |
210 | ; 7. Return. |
Line 250... | Line 228... | ||
250 | ; 3. Check that the handle is non-zero. |
228 | ; 3. Check that the handle is non-zero. |
251 | ; Otherwise, return the corresponding error code. |
229 | ; Otherwise, return the corresponding error code. |
252 | test edx, edx |
230 | test edx, edx |
253 | jz .return |
231 | jz .return |
254 | ; 4. Delete the disk from the system. |
232 | ; 4. Delete the disk from the system. |
255 | stdcall DiskDel, edx |
233 | invoke DiskDel, edx |
256 | ; 5. Return success. |
234 | ; 5. Return success. |
257 | ; Note that we can't free memory yet; it will be done in tmpdisk_close. |
235 | ; Note that we can't free memory yet; it will be done in tmpdisk_close. |
258 | xor eax, eax |
236 | xor eax, eax |
259 | .return: |
237 | .return: |
260 | retn |
238 | retn |
Line 285... | Line 263... | ||
285 | times max_num_disks dd 0 |
263 | times max_num_disks dd 0 |
286 | ; disk_sizes = array of disk sizes |
264 | ; disk_sizes = array of disk sizes |
287 | label disk_sizes dword |
265 | label disk_sizes dword |
288 | times max_num_disks dd 0 |
266 | times max_num_disks dd 0 |
Line 289... | Line -... | ||
289 | - | ||
290 | version dd 0x00060006 |
267 | |
291 | my_service db 'tmpdisk',0 |
- | |
292 | - | ||
293 | ; uninitialized data |
- | |
294 | ; actually, not used here |
- |