1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * nt_io.c --- This is the Nt I/O interface to the I/O manager.
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Implements a one-block write-through cache.
5*6a54128fSAndroid Build Coastguard Worker *
6*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
7*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 1998 Andrey Shedel ([email protected])
8*6a54128fSAndroid Build Coastguard Worker *
9*6a54128fSAndroid Build Coastguard Worker * %Begin-Header%
10*6a54128fSAndroid Build Coastguard Worker * This file may be redistributed under the terms of the GNU Library
11*6a54128fSAndroid Build Coastguard Worker * General Public License, version 2.
12*6a54128fSAndroid Build Coastguard Worker * %End-Header%
13*6a54128fSAndroid Build Coastguard Worker */
14*6a54128fSAndroid Build Coastguard Worker
15*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
16*6a54128fSAndroid Build Coastguard Worker #include "config.h"
17*6a54128fSAndroid Build Coastguard Worker #endif
18*6a54128fSAndroid Build Coastguard Worker
19*6a54128fSAndroid Build Coastguard Worker
20*6a54128fSAndroid Build Coastguard Worker //
21*6a54128fSAndroid Build Coastguard Worker // I need some warnings to disable...
22*6a54128fSAndroid Build Coastguard Worker //
23*6a54128fSAndroid Build Coastguard Worker
24*6a54128fSAndroid Build Coastguard Worker
25*6a54128fSAndroid Build Coastguard Worker #pragma warning(disable:4514) // unreferenced inline function has been removed
26*6a54128fSAndroid Build Coastguard Worker #pragma warning(push,4)
27*6a54128fSAndroid Build Coastguard Worker
28*6a54128fSAndroid Build Coastguard Worker #pragma warning(disable:4201) // nonstandard extension used : nameless struct/union)
29*6a54128fSAndroid Build Coastguard Worker #pragma warning(disable:4214) // nonstandard extension used : bit field types other than int
30*6a54128fSAndroid Build Coastguard Worker #pragma warning(disable:4115) // named type definition in parentheses
31*6a54128fSAndroid Build Coastguard Worker
32*6a54128fSAndroid Build Coastguard Worker #include <ntddk.h>
33*6a54128fSAndroid Build Coastguard Worker #include <ntdddisk.h>
34*6a54128fSAndroid Build Coastguard Worker #include <ntstatus.h>
35*6a54128fSAndroid Build Coastguard Worker
36*6a54128fSAndroid Build Coastguard Worker #pragma warning(pop)
37*6a54128fSAndroid Build Coastguard Worker
38*6a54128fSAndroid Build Coastguard Worker
39*6a54128fSAndroid Build Coastguard Worker //
40*6a54128fSAndroid Build Coastguard Worker // Some native APIs.
41*6a54128fSAndroid Build Coastguard Worker //
42*6a54128fSAndroid Build Coastguard Worker
43*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
44*6a54128fSAndroid Build Coastguard Worker ULONG
45*6a54128fSAndroid Build Coastguard Worker NTAPI
46*6a54128fSAndroid Build Coastguard Worker RtlNtStatusToDosError(
47*6a54128fSAndroid Build Coastguard Worker IN NTSTATUS Status
48*6a54128fSAndroid Build Coastguard Worker );
49*6a54128fSAndroid Build Coastguard Worker
50*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
51*6a54128fSAndroid Build Coastguard Worker NTSTATUS
52*6a54128fSAndroid Build Coastguard Worker NTAPI
53*6a54128fSAndroid Build Coastguard Worker NtClose(
54*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle
55*6a54128fSAndroid Build Coastguard Worker );
56*6a54128fSAndroid Build Coastguard Worker
57*6a54128fSAndroid Build Coastguard Worker
58*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
59*6a54128fSAndroid Build Coastguard Worker NTSTATUS
60*6a54128fSAndroid Build Coastguard Worker NTAPI
61*6a54128fSAndroid Build Coastguard Worker NtOpenFile(
62*6a54128fSAndroid Build Coastguard Worker OUT PHANDLE FileHandle,
63*6a54128fSAndroid Build Coastguard Worker IN ACCESS_MASK DesiredAccess,
64*6a54128fSAndroid Build Coastguard Worker IN POBJECT_ATTRIBUTES ObjectAttributes,
65*6a54128fSAndroid Build Coastguard Worker OUT PIO_STATUS_BLOCK IoStatusBlock,
66*6a54128fSAndroid Build Coastguard Worker IN ULONG ShareAccess,
67*6a54128fSAndroid Build Coastguard Worker IN ULONG OpenOptions
68*6a54128fSAndroid Build Coastguard Worker );
69*6a54128fSAndroid Build Coastguard Worker
70*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
71*6a54128fSAndroid Build Coastguard Worker NTSTATUS
72*6a54128fSAndroid Build Coastguard Worker NTAPI
73*6a54128fSAndroid Build Coastguard Worker NtFlushBuffersFile(
74*6a54128fSAndroid Build Coastguard Worker IN HANDLE FileHandle,
75*6a54128fSAndroid Build Coastguard Worker OUT PIO_STATUS_BLOCK IoStatusBlock
76*6a54128fSAndroid Build Coastguard Worker );
77*6a54128fSAndroid Build Coastguard Worker
78*6a54128fSAndroid Build Coastguard Worker
79*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
80*6a54128fSAndroid Build Coastguard Worker NTSTATUS
81*6a54128fSAndroid Build Coastguard Worker NTAPI
82*6a54128fSAndroid Build Coastguard Worker NtReadFile(
83*6a54128fSAndroid Build Coastguard Worker IN HANDLE FileHandle,
84*6a54128fSAndroid Build Coastguard Worker IN HANDLE Event OPTIONAL,
85*6a54128fSAndroid Build Coastguard Worker IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
86*6a54128fSAndroid Build Coastguard Worker IN PVOID ApcContext OPTIONAL,
87*6a54128fSAndroid Build Coastguard Worker OUT PIO_STATUS_BLOCK IoStatusBlock,
88*6a54128fSAndroid Build Coastguard Worker OUT PVOID Buffer,
89*6a54128fSAndroid Build Coastguard Worker IN ULONG Length,
90*6a54128fSAndroid Build Coastguard Worker IN PLARGE_INTEGER ByteOffset OPTIONAL,
91*6a54128fSAndroid Build Coastguard Worker IN PULONG Key OPTIONAL
92*6a54128fSAndroid Build Coastguard Worker );
93*6a54128fSAndroid Build Coastguard Worker
94*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
95*6a54128fSAndroid Build Coastguard Worker NTSTATUS
96*6a54128fSAndroid Build Coastguard Worker NTAPI
97*6a54128fSAndroid Build Coastguard Worker NtWriteFile(
98*6a54128fSAndroid Build Coastguard Worker IN HANDLE FileHandle,
99*6a54128fSAndroid Build Coastguard Worker IN HANDLE Event OPTIONAL,
100*6a54128fSAndroid Build Coastguard Worker IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
101*6a54128fSAndroid Build Coastguard Worker IN PVOID ApcContext OPTIONAL,
102*6a54128fSAndroid Build Coastguard Worker OUT PIO_STATUS_BLOCK IoStatusBlock,
103*6a54128fSAndroid Build Coastguard Worker IN PVOID Buffer,
104*6a54128fSAndroid Build Coastguard Worker IN ULONG Length,
105*6a54128fSAndroid Build Coastguard Worker IN PLARGE_INTEGER ByteOffset OPTIONAL,
106*6a54128fSAndroid Build Coastguard Worker IN PULONG Key OPTIONAL
107*6a54128fSAndroid Build Coastguard Worker );
108*6a54128fSAndroid Build Coastguard Worker
109*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
110*6a54128fSAndroid Build Coastguard Worker NTSTATUS
111*6a54128fSAndroid Build Coastguard Worker NTAPI
112*6a54128fSAndroid Build Coastguard Worker NtDeviceIoControlFile(
113*6a54128fSAndroid Build Coastguard Worker IN HANDLE FileHandle,
114*6a54128fSAndroid Build Coastguard Worker IN HANDLE Event OPTIONAL,
115*6a54128fSAndroid Build Coastguard Worker IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
116*6a54128fSAndroid Build Coastguard Worker IN PVOID ApcContext OPTIONAL,
117*6a54128fSAndroid Build Coastguard Worker OUT PIO_STATUS_BLOCK IoStatusBlock,
118*6a54128fSAndroid Build Coastguard Worker IN ULONG IoControlCode,
119*6a54128fSAndroid Build Coastguard Worker IN PVOID InputBuffer OPTIONAL,
120*6a54128fSAndroid Build Coastguard Worker IN ULONG InputBufferLength,
121*6a54128fSAndroid Build Coastguard Worker OUT PVOID OutputBuffer OPTIONAL,
122*6a54128fSAndroid Build Coastguard Worker IN ULONG OutputBufferLength
123*6a54128fSAndroid Build Coastguard Worker );
124*6a54128fSAndroid Build Coastguard Worker
125*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
126*6a54128fSAndroid Build Coastguard Worker NTSTATUS
127*6a54128fSAndroid Build Coastguard Worker NTAPI
128*6a54128fSAndroid Build Coastguard Worker NtFsControlFile(
129*6a54128fSAndroid Build Coastguard Worker IN HANDLE FileHandle,
130*6a54128fSAndroid Build Coastguard Worker IN HANDLE Event OPTIONAL,
131*6a54128fSAndroid Build Coastguard Worker IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
132*6a54128fSAndroid Build Coastguard Worker IN PVOID ApcContext OPTIONAL,
133*6a54128fSAndroid Build Coastguard Worker OUT PIO_STATUS_BLOCK IoStatusBlock,
134*6a54128fSAndroid Build Coastguard Worker IN ULONG IoControlCode,
135*6a54128fSAndroid Build Coastguard Worker IN PVOID InputBuffer OPTIONAL,
136*6a54128fSAndroid Build Coastguard Worker IN ULONG InputBufferLength,
137*6a54128fSAndroid Build Coastguard Worker OUT PVOID OutputBuffer OPTIONAL,
138*6a54128fSAndroid Build Coastguard Worker IN ULONG OutputBufferLength
139*6a54128fSAndroid Build Coastguard Worker );
140*6a54128fSAndroid Build Coastguard Worker
141*6a54128fSAndroid Build Coastguard Worker
142*6a54128fSAndroid Build Coastguard Worker NTSYSAPI
143*6a54128fSAndroid Build Coastguard Worker NTSTATUS
144*6a54128fSAndroid Build Coastguard Worker NTAPI
145*6a54128fSAndroid Build Coastguard Worker NtDelayExecution(
146*6a54128fSAndroid Build Coastguard Worker IN BOOLEAN Alertable,
147*6a54128fSAndroid Build Coastguard Worker IN PLARGE_INTEGER Interval
148*6a54128fSAndroid Build Coastguard Worker );
149*6a54128fSAndroid Build Coastguard Worker
150*6a54128fSAndroid Build Coastguard Worker
151*6a54128fSAndroid Build Coastguard Worker #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
152*6a54128fSAndroid Build Coastguard Worker #define FSCTL_UNLOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
153*6a54128fSAndroid Build Coastguard Worker #define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
154*6a54128fSAndroid Build Coastguard Worker #define FSCTL_IS_VOLUME_MOUNTED CTL_CODE(FILE_DEVICE_FILE_SYSTEM,10, METHOD_BUFFERED, FILE_ANY_ACCESS)
155*6a54128fSAndroid Build Coastguard Worker
156*6a54128fSAndroid Build Coastguard Worker
157*6a54128fSAndroid Build Coastguard Worker //
158*6a54128fSAndroid Build Coastguard Worker // useful macros
159*6a54128fSAndroid Build Coastguard Worker //
160*6a54128fSAndroid Build Coastguard Worker
161*6a54128fSAndroid Build Coastguard Worker #define BooleanFlagOn(Flags,SingleFlag) ((BOOLEAN)((((Flags) & (SingleFlag)) != 0)))
162*6a54128fSAndroid Build Coastguard Worker
163*6a54128fSAndroid Build Coastguard Worker
164*6a54128fSAndroid Build Coastguard Worker //
165*6a54128fSAndroid Build Coastguard Worker // Include Win32 error codes.
166*6a54128fSAndroid Build Coastguard Worker //
167*6a54128fSAndroid Build Coastguard Worker
168*6a54128fSAndroid Build Coastguard Worker #include <winerror.h>
169*6a54128fSAndroid Build Coastguard Worker
170*6a54128fSAndroid Build Coastguard Worker //
171*6a54128fSAndroid Build Coastguard Worker // standard stuff
172*6a54128fSAndroid Build Coastguard Worker //
173*6a54128fSAndroid Build Coastguard Worker
174*6a54128fSAndroid Build Coastguard Worker #include <assert.h>
175*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
176*6a54128fSAndroid Build Coastguard Worker #include <string.h>
177*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
178*6a54128fSAndroid Build Coastguard Worker #include <malloc.h>
179*6a54128fSAndroid Build Coastguard Worker
180*6a54128fSAndroid Build Coastguard Worker #include <linux/types.h>
181*6a54128fSAndroid Build Coastguard Worker #include "ext2_fs.h"
182*6a54128fSAndroid Build Coastguard Worker #include <errno.h>
183*6a54128fSAndroid Build Coastguard Worker
184*6a54128fSAndroid Build Coastguard Worker #include "et/com_err.h"
185*6a54128fSAndroid Build Coastguard Worker #include "ext2fs/ext2fs.h"
186*6a54128fSAndroid Build Coastguard Worker #include "ext2fs/ext2_err.h"
187*6a54128fSAndroid Build Coastguard Worker
188*6a54128fSAndroid Build Coastguard Worker
189*6a54128fSAndroid Build Coastguard Worker
190*6a54128fSAndroid Build Coastguard Worker
191*6a54128fSAndroid Build Coastguard Worker //
192*6a54128fSAndroid Build Coastguard Worker // For checking structure magic numbers...
193*6a54128fSAndroid Build Coastguard Worker //
194*6a54128fSAndroid Build Coastguard Worker
195*6a54128fSAndroid Build Coastguard Worker
196*6a54128fSAndroid Build Coastguard Worker #define EXT2_CHECK_MAGIC(struct, code) \
197*6a54128fSAndroid Build Coastguard Worker if ((struct)->magic != (code)) return (code)
198*6a54128fSAndroid Build Coastguard Worker
199*6a54128fSAndroid Build Coastguard Worker #define EXT2_ET_MAGIC_NT_IO_CHANNEL 0x10ed
200*6a54128fSAndroid Build Coastguard Worker
201*6a54128fSAndroid Build Coastguard Worker
202*6a54128fSAndroid Build Coastguard Worker //
203*6a54128fSAndroid Build Coastguard Worker // Private data block
204*6a54128fSAndroid Build Coastguard Worker //
205*6a54128fSAndroid Build Coastguard Worker
206*6a54128fSAndroid Build Coastguard Worker typedef struct _NT_PRIVATE_DATA {
207*6a54128fSAndroid Build Coastguard Worker int magic;
208*6a54128fSAndroid Build Coastguard Worker HANDLE Handle;
209*6a54128fSAndroid Build Coastguard Worker int Flags;
210*6a54128fSAndroid Build Coastguard Worker PCHAR Buffer;
211*6a54128fSAndroid Build Coastguard Worker __u32 BufferBlockNumber;
212*6a54128fSAndroid Build Coastguard Worker ULONG BufferSize;
213*6a54128fSAndroid Build Coastguard Worker BOOLEAN OpenedReadonly;
214*6a54128fSAndroid Build Coastguard Worker BOOLEAN Written;
215*6a54128fSAndroid Build Coastguard Worker }NT_PRIVATE_DATA, *PNT_PRIVATE_DATA;
216*6a54128fSAndroid Build Coastguard Worker
217*6a54128fSAndroid Build Coastguard Worker
218*6a54128fSAndroid Build Coastguard Worker
219*6a54128fSAndroid Build Coastguard Worker //
220*6a54128fSAndroid Build Coastguard Worker // Standard interface prototypes
221*6a54128fSAndroid Build Coastguard Worker //
222*6a54128fSAndroid Build Coastguard Worker
223*6a54128fSAndroid Build Coastguard Worker static errcode_t nt_open(const char *name, int flags, io_channel *channel);
224*6a54128fSAndroid Build Coastguard Worker static errcode_t nt_close(io_channel channel);
225*6a54128fSAndroid Build Coastguard Worker static errcode_t nt_set_blksize(io_channel channel, int blksize);
226*6a54128fSAndroid Build Coastguard Worker static errcode_t nt_read_blk(io_channel channel, unsigned long block,
227*6a54128fSAndroid Build Coastguard Worker int count, void *data);
228*6a54128fSAndroid Build Coastguard Worker static errcode_t nt_write_blk(io_channel channel, unsigned long block,
229*6a54128fSAndroid Build Coastguard Worker int count, const void *data);
230*6a54128fSAndroid Build Coastguard Worker static errcode_t nt_flush(io_channel channel);
231*6a54128fSAndroid Build Coastguard Worker
232*6a54128fSAndroid Build Coastguard Worker static struct struct_io_manager struct_nt_manager = {
233*6a54128fSAndroid Build Coastguard Worker .magic = EXT2_ET_MAGIC_IO_MANAGER,
234*6a54128fSAndroid Build Coastguard Worker .name = "NT I/O Manager",
235*6a54128fSAndroid Build Coastguard Worker .open = nt_open,
236*6a54128fSAndroid Build Coastguard Worker .close = nt_close,
237*6a54128fSAndroid Build Coastguard Worker .set_blksize = nt_set_blksize,
238*6a54128fSAndroid Build Coastguard Worker .read_blk = nt_read_blk,
239*6a54128fSAndroid Build Coastguard Worker .write_blk = nt_write_blk,
240*6a54128fSAndroid Build Coastguard Worker .flush = nt_flush
241*6a54128fSAndroid Build Coastguard Worker };
242*6a54128fSAndroid Build Coastguard Worker
243*6a54128fSAndroid Build Coastguard Worker //
244*6a54128fSAndroid Build Coastguard Worker // function to get API
245*6a54128fSAndroid Build Coastguard Worker //
246*6a54128fSAndroid Build Coastguard Worker
nt_io_manager()247*6a54128fSAndroid Build Coastguard Worker io_manager nt_io_manager()
248*6a54128fSAndroid Build Coastguard Worker {
249*6a54128fSAndroid Build Coastguard Worker return &struct_nt_manager;
250*6a54128fSAndroid Build Coastguard Worker }
251*6a54128fSAndroid Build Coastguard Worker
252*6a54128fSAndroid Build Coastguard Worker
253*6a54128fSAndroid Build Coastguard Worker
254*6a54128fSAndroid Build Coastguard Worker
255*6a54128fSAndroid Build Coastguard Worker
256*6a54128fSAndroid Build Coastguard Worker //
257*6a54128fSAndroid Build Coastguard Worker // This is a code to convert Win32 errors to unix errno
258*6a54128fSAndroid Build Coastguard Worker //
259*6a54128fSAndroid Build Coastguard Worker
260*6a54128fSAndroid Build Coastguard Worker typedef struct {
261*6a54128fSAndroid Build Coastguard Worker ULONG WinError;
262*6a54128fSAndroid Build Coastguard Worker int errnocode;
263*6a54128fSAndroid Build Coastguard Worker }ERROR_ENTRY;
264*6a54128fSAndroid Build Coastguard Worker
265*6a54128fSAndroid Build Coastguard Worker static ERROR_ENTRY ErrorTable[] = {
266*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_FUNCTION, EINVAL },
267*6a54128fSAndroid Build Coastguard Worker { ERROR_FILE_NOT_FOUND, ENOENT },
268*6a54128fSAndroid Build Coastguard Worker { ERROR_PATH_NOT_FOUND, ENOENT },
269*6a54128fSAndroid Build Coastguard Worker { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
270*6a54128fSAndroid Build Coastguard Worker { ERROR_ACCESS_DENIED, EACCES },
271*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_HANDLE, EBADF },
272*6a54128fSAndroid Build Coastguard Worker { ERROR_ARENA_TRASHED, ENOMEM },
273*6a54128fSAndroid Build Coastguard Worker { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
274*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_BLOCK, ENOMEM },
275*6a54128fSAndroid Build Coastguard Worker { ERROR_BAD_ENVIRONMENT, E2BIG },
276*6a54128fSAndroid Build Coastguard Worker { ERROR_BAD_FORMAT, ENOEXEC },
277*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_ACCESS, EINVAL },
278*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_DATA, EINVAL },
279*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_DRIVE, ENOENT },
280*6a54128fSAndroid Build Coastguard Worker { ERROR_CURRENT_DIRECTORY, EACCES },
281*6a54128fSAndroid Build Coastguard Worker { ERROR_NOT_SAME_DEVICE, EXDEV },
282*6a54128fSAndroid Build Coastguard Worker { ERROR_NO_MORE_FILES, ENOENT },
283*6a54128fSAndroid Build Coastguard Worker { ERROR_LOCK_VIOLATION, EACCES },
284*6a54128fSAndroid Build Coastguard Worker { ERROR_BAD_NETPATH, ENOENT },
285*6a54128fSAndroid Build Coastguard Worker { ERROR_NETWORK_ACCESS_DENIED, EACCES },
286*6a54128fSAndroid Build Coastguard Worker { ERROR_BAD_NET_NAME, ENOENT },
287*6a54128fSAndroid Build Coastguard Worker { ERROR_FILE_EXISTS, EEXIST },
288*6a54128fSAndroid Build Coastguard Worker { ERROR_CANNOT_MAKE, EACCES },
289*6a54128fSAndroid Build Coastguard Worker { ERROR_FAIL_I24, EACCES },
290*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_PARAMETER, EINVAL },
291*6a54128fSAndroid Build Coastguard Worker { ERROR_NO_PROC_SLOTS, EAGAIN },
292*6a54128fSAndroid Build Coastguard Worker { ERROR_DRIVE_LOCKED, EACCES },
293*6a54128fSAndroid Build Coastguard Worker { ERROR_BROKEN_PIPE, EPIPE },
294*6a54128fSAndroid Build Coastguard Worker { ERROR_DISK_FULL, ENOSPC },
295*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_TARGET_HANDLE, EBADF },
296*6a54128fSAndroid Build Coastguard Worker { ERROR_INVALID_HANDLE, EINVAL },
297*6a54128fSAndroid Build Coastguard Worker { ERROR_WAIT_NO_CHILDREN, ECHILD },
298*6a54128fSAndroid Build Coastguard Worker { ERROR_CHILD_NOT_COMPLETE, ECHILD },
299*6a54128fSAndroid Build Coastguard Worker { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
300*6a54128fSAndroid Build Coastguard Worker { ERROR_NEGATIVE_SEEK, EINVAL },
301*6a54128fSAndroid Build Coastguard Worker { ERROR_SEEK_ON_DEVICE, EACCES },
302*6a54128fSAndroid Build Coastguard Worker { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
303*6a54128fSAndroid Build Coastguard Worker { ERROR_NOT_LOCKED, EACCES },
304*6a54128fSAndroid Build Coastguard Worker { ERROR_BAD_PATHNAME, ENOENT },
305*6a54128fSAndroid Build Coastguard Worker { ERROR_MAX_THRDS_REACHED, EAGAIN },
306*6a54128fSAndroid Build Coastguard Worker { ERROR_LOCK_FAILED, EACCES },
307*6a54128fSAndroid Build Coastguard Worker { ERROR_ALREADY_EXISTS, EEXIST },
308*6a54128fSAndroid Build Coastguard Worker { ERROR_FILENAME_EXCED_RANGE, ENOENT },
309*6a54128fSAndroid Build Coastguard Worker { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
310*6a54128fSAndroid Build Coastguard Worker { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
311*6a54128fSAndroid Build Coastguard Worker };
312*6a54128fSAndroid Build Coastguard Worker
313*6a54128fSAndroid Build Coastguard Worker
314*6a54128fSAndroid Build Coastguard Worker
315*6a54128fSAndroid Build Coastguard Worker
316*6a54128fSAndroid Build Coastguard Worker static
317*6a54128fSAndroid Build Coastguard Worker unsigned
_MapDosError(IN ULONG WinError)318*6a54128fSAndroid Build Coastguard Worker _MapDosError (
319*6a54128fSAndroid Build Coastguard Worker IN ULONG WinError
320*6a54128fSAndroid Build Coastguard Worker )
321*6a54128fSAndroid Build Coastguard Worker {
322*6a54128fSAndroid Build Coastguard Worker int i;
323*6a54128fSAndroid Build Coastguard Worker
324*6a54128fSAndroid Build Coastguard Worker //
325*6a54128fSAndroid Build Coastguard Worker // Lookup
326*6a54128fSAndroid Build Coastguard Worker //
327*6a54128fSAndroid Build Coastguard Worker
328*6a54128fSAndroid Build Coastguard Worker for (i = 0; i < (sizeof(ErrorTable)/sizeof(ErrorTable[0])); ++i)
329*6a54128fSAndroid Build Coastguard Worker {
330*6a54128fSAndroid Build Coastguard Worker if (WinError == ErrorTable[i].WinError)
331*6a54128fSAndroid Build Coastguard Worker {
332*6a54128fSAndroid Build Coastguard Worker return ErrorTable[i].errnocode;
333*6a54128fSAndroid Build Coastguard Worker }
334*6a54128fSAndroid Build Coastguard Worker }
335*6a54128fSAndroid Build Coastguard Worker
336*6a54128fSAndroid Build Coastguard Worker //
337*6a54128fSAndroid Build Coastguard Worker // not in table. Check ranges
338*6a54128fSAndroid Build Coastguard Worker //
339*6a54128fSAndroid Build Coastguard Worker
340*6a54128fSAndroid Build Coastguard Worker if ((WinError >= ERROR_WRITE_PROTECT) &&
341*6a54128fSAndroid Build Coastguard Worker (WinError <= ERROR_SHARING_BUFFER_EXCEEDED))
342*6a54128fSAndroid Build Coastguard Worker {
343*6a54128fSAndroid Build Coastguard Worker return EACCES;
344*6a54128fSAndroid Build Coastguard Worker }
345*6a54128fSAndroid Build Coastguard Worker else if ((WinError >= ERROR_INVALID_STARTING_CODESEG) &&
346*6a54128fSAndroid Build Coastguard Worker (WinError <= ERROR_INFLOOP_IN_RELOC_CHAIN))
347*6a54128fSAndroid Build Coastguard Worker {
348*6a54128fSAndroid Build Coastguard Worker return ENOEXEC;
349*6a54128fSAndroid Build Coastguard Worker }
350*6a54128fSAndroid Build Coastguard Worker else
351*6a54128fSAndroid Build Coastguard Worker {
352*6a54128fSAndroid Build Coastguard Worker return EINVAL;
353*6a54128fSAndroid Build Coastguard Worker }
354*6a54128fSAndroid Build Coastguard Worker }
355*6a54128fSAndroid Build Coastguard Worker
356*6a54128fSAndroid Build Coastguard Worker
357*6a54128fSAndroid Build Coastguard Worker
358*6a54128fSAndroid Build Coastguard Worker
359*6a54128fSAndroid Build Coastguard Worker
360*6a54128fSAndroid Build Coastguard Worker
361*6a54128fSAndroid Build Coastguard Worker
362*6a54128fSAndroid Build Coastguard Worker //
363*6a54128fSAndroid Build Coastguard Worker // Function to map NT status to dos error.
364*6a54128fSAndroid Build Coastguard Worker //
365*6a54128fSAndroid Build Coastguard Worker
366*6a54128fSAndroid Build Coastguard Worker static
367*6a54128fSAndroid Build Coastguard Worker __inline
368*6a54128fSAndroid Build Coastguard Worker unsigned
_MapNtStatus(IN NTSTATUS Status)369*6a54128fSAndroid Build Coastguard Worker _MapNtStatus(
370*6a54128fSAndroid Build Coastguard Worker IN NTSTATUS Status
371*6a54128fSAndroid Build Coastguard Worker )
372*6a54128fSAndroid Build Coastguard Worker {
373*6a54128fSAndroid Build Coastguard Worker return _MapDosError(RtlNtStatusToDosError(Status));
374*6a54128fSAndroid Build Coastguard Worker }
375*6a54128fSAndroid Build Coastguard Worker
376*6a54128fSAndroid Build Coastguard Worker
377*6a54128fSAndroid Build Coastguard Worker
378*6a54128fSAndroid Build Coastguard Worker
379*6a54128fSAndroid Build Coastguard Worker
380*6a54128fSAndroid Build Coastguard Worker //
381*6a54128fSAndroid Build Coastguard Worker // Helper functions to make things easier
382*6a54128fSAndroid Build Coastguard Worker //
383*6a54128fSAndroid Build Coastguard Worker
384*6a54128fSAndroid Build Coastguard Worker static
385*6a54128fSAndroid Build Coastguard Worker NTSTATUS
_OpenNtName(IN PCSTR Name,IN BOOLEAN Readonly,OUT PHANDLE Handle,OUT PBOOLEAN OpenedReadonly OPTIONAL)386*6a54128fSAndroid Build Coastguard Worker _OpenNtName(
387*6a54128fSAndroid Build Coastguard Worker IN PCSTR Name,
388*6a54128fSAndroid Build Coastguard Worker IN BOOLEAN Readonly,
389*6a54128fSAndroid Build Coastguard Worker OUT PHANDLE Handle,
390*6a54128fSAndroid Build Coastguard Worker OUT PBOOLEAN OpenedReadonly OPTIONAL
391*6a54128fSAndroid Build Coastguard Worker )
392*6a54128fSAndroid Build Coastguard Worker {
393*6a54128fSAndroid Build Coastguard Worker UNICODE_STRING UnicodeString;
394*6a54128fSAndroid Build Coastguard Worker ANSI_STRING AnsiString;
395*6a54128fSAndroid Build Coastguard Worker WCHAR Buffer[512];
396*6a54128fSAndroid Build Coastguard Worker NTSTATUS Status;
397*6a54128fSAndroid Build Coastguard Worker OBJECT_ATTRIBUTES ObjectAttributes;
398*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
399*6a54128fSAndroid Build Coastguard Worker
400*6a54128fSAndroid Build Coastguard Worker //
401*6a54128fSAndroid Build Coastguard Worker // Make Unicode name from input string
402*6a54128fSAndroid Build Coastguard Worker //
403*6a54128fSAndroid Build Coastguard Worker
404*6a54128fSAndroid Build Coastguard Worker UnicodeString.Buffer = &Buffer[0];
405*6a54128fSAndroid Build Coastguard Worker UnicodeString.Length = 0;
406*6a54128fSAndroid Build Coastguard Worker UnicodeString.MaximumLength = sizeof(Buffer); // in bytes!!!
407*6a54128fSAndroid Build Coastguard Worker
408*6a54128fSAndroid Build Coastguard Worker RtlInitAnsiString(&AnsiString, Name);
409*6a54128fSAndroid Build Coastguard Worker
410*6a54128fSAndroid Build Coastguard Worker Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
411*6a54128fSAndroid Build Coastguard Worker
412*6a54128fSAndroid Build Coastguard Worker if(!NT_SUCCESS(Status))
413*6a54128fSAndroid Build Coastguard Worker {
414*6a54128fSAndroid Build Coastguard Worker return Status; // Unmappable character?
415*6a54128fSAndroid Build Coastguard Worker }
416*6a54128fSAndroid Build Coastguard Worker
417*6a54128fSAndroid Build Coastguard Worker //
418*6a54128fSAndroid Build Coastguard Worker // Initialize object
419*6a54128fSAndroid Build Coastguard Worker //
420*6a54128fSAndroid Build Coastguard Worker
421*6a54128fSAndroid Build Coastguard Worker InitializeObjectAttributes(&ObjectAttributes,
422*6a54128fSAndroid Build Coastguard Worker &UnicodeString,
423*6a54128fSAndroid Build Coastguard Worker OBJ_CASE_INSENSITIVE,
424*6a54128fSAndroid Build Coastguard Worker NULL,
425*6a54128fSAndroid Build Coastguard Worker NULL );
426*6a54128fSAndroid Build Coastguard Worker
427*6a54128fSAndroid Build Coastguard Worker //
428*6a54128fSAndroid Build Coastguard Worker // Try to open it in initial mode
429*6a54128fSAndroid Build Coastguard Worker //
430*6a54128fSAndroid Build Coastguard Worker
431*6a54128fSAndroid Build Coastguard Worker if(ARGUMENT_PRESENT(OpenedReadonly))
432*6a54128fSAndroid Build Coastguard Worker {
433*6a54128fSAndroid Build Coastguard Worker *OpenedReadonly = Readonly;
434*6a54128fSAndroid Build Coastguard Worker }
435*6a54128fSAndroid Build Coastguard Worker
436*6a54128fSAndroid Build Coastguard Worker
437*6a54128fSAndroid Build Coastguard Worker Status = NtOpenFile(Handle,
438*6a54128fSAndroid Build Coastguard Worker SYNCHRONIZE | FILE_READ_DATA | (Readonly ? 0 : FILE_WRITE_DATA),
439*6a54128fSAndroid Build Coastguard Worker &ObjectAttributes,
440*6a54128fSAndroid Build Coastguard Worker &IoStatusBlock,
441*6a54128fSAndroid Build Coastguard Worker FILE_SHARE_WRITE | FILE_SHARE_READ,
442*6a54128fSAndroid Build Coastguard Worker FILE_SYNCHRONOUS_IO_NONALERT);
443*6a54128fSAndroid Build Coastguard Worker
444*6a54128fSAndroid Build Coastguard Worker if(!NT_SUCCESS(Status))
445*6a54128fSAndroid Build Coastguard Worker {
446*6a54128fSAndroid Build Coastguard Worker //
447*6a54128fSAndroid Build Coastguard Worker // Maybe was just mounted? wait 0.5 sec and retry.
448*6a54128fSAndroid Build Coastguard Worker //
449*6a54128fSAndroid Build Coastguard Worker
450*6a54128fSAndroid Build Coastguard Worker LARGE_INTEGER Interval;
451*6a54128fSAndroid Build Coastguard Worker Interval.QuadPart = -5000000; // 0.5 sec. from now
452*6a54128fSAndroid Build Coastguard Worker
453*6a54128fSAndroid Build Coastguard Worker NtDelayExecution(FALSE, &Interval);
454*6a54128fSAndroid Build Coastguard Worker
455*6a54128fSAndroid Build Coastguard Worker Status = NtOpenFile(Handle,
456*6a54128fSAndroid Build Coastguard Worker SYNCHRONIZE | FILE_READ_DATA | (Readonly ? 0 : FILE_WRITE_DATA),
457*6a54128fSAndroid Build Coastguard Worker &ObjectAttributes,
458*6a54128fSAndroid Build Coastguard Worker &IoStatusBlock,
459*6a54128fSAndroid Build Coastguard Worker FILE_SHARE_WRITE | FILE_SHARE_READ,
460*6a54128fSAndroid Build Coastguard Worker FILE_SYNCHRONOUS_IO_NONALERT);
461*6a54128fSAndroid Build Coastguard Worker
462*6a54128fSAndroid Build Coastguard Worker //
463*6a54128fSAndroid Build Coastguard Worker // Try to satisfy mode
464*6a54128fSAndroid Build Coastguard Worker //
465*6a54128fSAndroid Build Coastguard Worker
466*6a54128fSAndroid Build Coastguard Worker if((STATUS_ACCESS_DENIED == Status) && !Readonly)
467*6a54128fSAndroid Build Coastguard Worker {
468*6a54128fSAndroid Build Coastguard Worker if(ARGUMENT_PRESENT(OpenedReadonly))
469*6a54128fSAndroid Build Coastguard Worker {
470*6a54128fSAndroid Build Coastguard Worker *OpenedReadonly = TRUE;
471*6a54128fSAndroid Build Coastguard Worker }
472*6a54128fSAndroid Build Coastguard Worker
473*6a54128fSAndroid Build Coastguard Worker Status = NtOpenFile(Handle,
474*6a54128fSAndroid Build Coastguard Worker SYNCHRONIZE | FILE_READ_DATA,
475*6a54128fSAndroid Build Coastguard Worker &ObjectAttributes,
476*6a54128fSAndroid Build Coastguard Worker &IoStatusBlock,
477*6a54128fSAndroid Build Coastguard Worker FILE_SHARE_WRITE | FILE_SHARE_READ,
478*6a54128fSAndroid Build Coastguard Worker FILE_SYNCHRONOUS_IO_NONALERT);
479*6a54128fSAndroid Build Coastguard Worker }
480*6a54128fSAndroid Build Coastguard Worker }
481*6a54128fSAndroid Build Coastguard Worker
482*6a54128fSAndroid Build Coastguard Worker
483*6a54128fSAndroid Build Coastguard Worker
484*6a54128fSAndroid Build Coastguard Worker //
485*6a54128fSAndroid Build Coastguard Worker // done
486*6a54128fSAndroid Build Coastguard Worker //
487*6a54128fSAndroid Build Coastguard Worker
488*6a54128fSAndroid Build Coastguard Worker return Status;
489*6a54128fSAndroid Build Coastguard Worker }
490*6a54128fSAndroid Build Coastguard Worker
491*6a54128fSAndroid Build Coastguard Worker
492*6a54128fSAndroid Build Coastguard Worker static
493*6a54128fSAndroid Build Coastguard Worker NTSTATUS
_OpenDriveLetter(IN CHAR Letter,IN BOOLEAN ReadOnly,OUT PHANDLE Handle,OUT PBOOLEAN OpenedReadonly OPTIONAL)494*6a54128fSAndroid Build Coastguard Worker _OpenDriveLetter(
495*6a54128fSAndroid Build Coastguard Worker IN CHAR Letter,
496*6a54128fSAndroid Build Coastguard Worker IN BOOLEAN ReadOnly,
497*6a54128fSAndroid Build Coastguard Worker OUT PHANDLE Handle,
498*6a54128fSAndroid Build Coastguard Worker OUT PBOOLEAN OpenedReadonly OPTIONAL
499*6a54128fSAndroid Build Coastguard Worker )
500*6a54128fSAndroid Build Coastguard Worker {
501*6a54128fSAndroid Build Coastguard Worker CHAR Buffer[100];
502*6a54128fSAndroid Build Coastguard Worker
503*6a54128fSAndroid Build Coastguard Worker sprintf(Buffer, "\\DosDevices\\%c:", Letter);
504*6a54128fSAndroid Build Coastguard Worker
505*6a54128fSAndroid Build Coastguard Worker return _OpenNtName(Buffer, ReadOnly, Handle, OpenedReadonly);
506*6a54128fSAndroid Build Coastguard Worker }
507*6a54128fSAndroid Build Coastguard Worker
508*6a54128fSAndroid Build Coastguard Worker
509*6a54128fSAndroid Build Coastguard Worker //
510*6a54128fSAndroid Build Coastguard Worker // Flush device
511*6a54128fSAndroid Build Coastguard Worker //
512*6a54128fSAndroid Build Coastguard Worker
513*6a54128fSAndroid Build Coastguard Worker static
514*6a54128fSAndroid Build Coastguard Worker __inline
515*6a54128fSAndroid Build Coastguard Worker NTSTATUS
_FlushDrive(IN HANDLE Handle)516*6a54128fSAndroid Build Coastguard Worker _FlushDrive(
517*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle
518*6a54128fSAndroid Build Coastguard Worker )
519*6a54128fSAndroid Build Coastguard Worker {
520*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
521*6a54128fSAndroid Build Coastguard Worker return NtFlushBuffersFile(Handle, &IoStatusBlock);
522*6a54128fSAndroid Build Coastguard Worker }
523*6a54128fSAndroid Build Coastguard Worker
524*6a54128fSAndroid Build Coastguard Worker
525*6a54128fSAndroid Build Coastguard Worker //
526*6a54128fSAndroid Build Coastguard Worker // lock drive
527*6a54128fSAndroid Build Coastguard Worker //
528*6a54128fSAndroid Build Coastguard Worker
529*6a54128fSAndroid Build Coastguard Worker static
530*6a54128fSAndroid Build Coastguard Worker __inline
531*6a54128fSAndroid Build Coastguard Worker NTSTATUS
_LockDrive(IN HANDLE Handle)532*6a54128fSAndroid Build Coastguard Worker _LockDrive(
533*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle
534*6a54128fSAndroid Build Coastguard Worker )
535*6a54128fSAndroid Build Coastguard Worker {
536*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
537*6a54128fSAndroid Build Coastguard Worker return NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
538*6a54128fSAndroid Build Coastguard Worker }
539*6a54128fSAndroid Build Coastguard Worker
540*6a54128fSAndroid Build Coastguard Worker
541*6a54128fSAndroid Build Coastguard Worker //
542*6a54128fSAndroid Build Coastguard Worker // unlock drive
543*6a54128fSAndroid Build Coastguard Worker //
544*6a54128fSAndroid Build Coastguard Worker
545*6a54128fSAndroid Build Coastguard Worker static
546*6a54128fSAndroid Build Coastguard Worker __inline
547*6a54128fSAndroid Build Coastguard Worker NTSTATUS
_UnlockDrive(IN HANDLE Handle)548*6a54128fSAndroid Build Coastguard Worker _UnlockDrive(
549*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle
550*6a54128fSAndroid Build Coastguard Worker )
551*6a54128fSAndroid Build Coastguard Worker {
552*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
553*6a54128fSAndroid Build Coastguard Worker return NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_UNLOCK_VOLUME, 0, 0, 0, 0);
554*6a54128fSAndroid Build Coastguard Worker }
555*6a54128fSAndroid Build Coastguard Worker
556*6a54128fSAndroid Build Coastguard Worker static
557*6a54128fSAndroid Build Coastguard Worker __inline
558*6a54128fSAndroid Build Coastguard Worker NTSTATUS
_DismountDrive(IN HANDLE Handle)559*6a54128fSAndroid Build Coastguard Worker _DismountDrive(
560*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle
561*6a54128fSAndroid Build Coastguard Worker )
562*6a54128fSAndroid Build Coastguard Worker {
563*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
564*6a54128fSAndroid Build Coastguard Worker return NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
565*6a54128fSAndroid Build Coastguard Worker }
566*6a54128fSAndroid Build Coastguard Worker
567*6a54128fSAndroid Build Coastguard Worker
568*6a54128fSAndroid Build Coastguard Worker //
569*6a54128fSAndroid Build Coastguard Worker // is mounted
570*6a54128fSAndroid Build Coastguard Worker //
571*6a54128fSAndroid Build Coastguard Worker
572*6a54128fSAndroid Build Coastguard Worker static
573*6a54128fSAndroid Build Coastguard Worker __inline
574*6a54128fSAndroid Build Coastguard Worker BOOLEAN
_IsMounted(IN HANDLE Handle)575*6a54128fSAndroid Build Coastguard Worker _IsMounted(
576*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle
577*6a54128fSAndroid Build Coastguard Worker )
578*6a54128fSAndroid Build Coastguard Worker {
579*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
580*6a54128fSAndroid Build Coastguard Worker NTSTATUS Status;
581*6a54128fSAndroid Build Coastguard Worker Status = NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_IS_VOLUME_MOUNTED, 0, 0, 0, 0);
582*6a54128fSAndroid Build Coastguard Worker return (BOOLEAN)(STATUS_SUCCESS == Status);
583*6a54128fSAndroid Build Coastguard Worker }
584*6a54128fSAndroid Build Coastguard Worker
585*6a54128fSAndroid Build Coastguard Worker
586*6a54128fSAndroid Build Coastguard Worker static
587*6a54128fSAndroid Build Coastguard Worker __inline
588*6a54128fSAndroid Build Coastguard Worker NTSTATUS
_CloseDisk(IN HANDLE Handle)589*6a54128fSAndroid Build Coastguard Worker _CloseDisk(
590*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle
591*6a54128fSAndroid Build Coastguard Worker )
592*6a54128fSAndroid Build Coastguard Worker {
593*6a54128fSAndroid Build Coastguard Worker return NtClose(Handle);
594*6a54128fSAndroid Build Coastguard Worker }
595*6a54128fSAndroid Build Coastguard Worker
596*6a54128fSAndroid Build Coastguard Worker
597*6a54128fSAndroid Build Coastguard Worker
598*6a54128fSAndroid Build Coastguard Worker
599*6a54128fSAndroid Build Coastguard Worker //
600*6a54128fSAndroid Build Coastguard Worker // Make NT name from any recognized name
601*6a54128fSAndroid Build Coastguard Worker //
602*6a54128fSAndroid Build Coastguard Worker
603*6a54128fSAndroid Build Coastguard Worker static
604*6a54128fSAndroid Build Coastguard Worker PCSTR
_NormalizeDeviceName(IN PCSTR Device,IN PSTR NormalizedDeviceNameBuffer)605*6a54128fSAndroid Build Coastguard Worker _NormalizeDeviceName(
606*6a54128fSAndroid Build Coastguard Worker IN PCSTR Device,
607*6a54128fSAndroid Build Coastguard Worker IN PSTR NormalizedDeviceNameBuffer
608*6a54128fSAndroid Build Coastguard Worker )
609*6a54128fSAndroid Build Coastguard Worker {
610*6a54128fSAndroid Build Coastguard Worker int PartitionNumber = -1;
611*6a54128fSAndroid Build Coastguard Worker UCHAR DiskNumber;
612*6a54128fSAndroid Build Coastguard Worker PSTR p;
613*6a54128fSAndroid Build Coastguard Worker
614*6a54128fSAndroid Build Coastguard Worker
615*6a54128fSAndroid Build Coastguard Worker //
616*6a54128fSAndroid Build Coastguard Worker // Do not try to parse NT name
617*6a54128fSAndroid Build Coastguard Worker //
618*6a54128fSAndroid Build Coastguard Worker
619*6a54128fSAndroid Build Coastguard Worker if('\\' == *Device)
620*6a54128fSAndroid Build Coastguard Worker return Device;
621*6a54128fSAndroid Build Coastguard Worker
622*6a54128fSAndroid Build Coastguard Worker
623*6a54128fSAndroid Build Coastguard Worker
624*6a54128fSAndroid Build Coastguard Worker //
625*6a54128fSAndroid Build Coastguard Worker // Strip leading '/dev/' if any
626*6a54128fSAndroid Build Coastguard Worker //
627*6a54128fSAndroid Build Coastguard Worker
628*6a54128fSAndroid Build Coastguard Worker if(('/' == *(Device)) &&
629*6a54128fSAndroid Build Coastguard Worker ('d' == *(Device + 1)) &&
630*6a54128fSAndroid Build Coastguard Worker ('e' == *(Device + 2)) &&
631*6a54128fSAndroid Build Coastguard Worker ('v' == *(Device + 3)) &&
632*6a54128fSAndroid Build Coastguard Worker ('/' == *(Device + 4)))
633*6a54128fSAndroid Build Coastguard Worker {
634*6a54128fSAndroid Build Coastguard Worker Device += 5;
635*6a54128fSAndroid Build Coastguard Worker }
636*6a54128fSAndroid Build Coastguard Worker
637*6a54128fSAndroid Build Coastguard Worker if('\0' == *Device)
638*6a54128fSAndroid Build Coastguard Worker {
639*6a54128fSAndroid Build Coastguard Worker return NULL;
640*6a54128fSAndroid Build Coastguard Worker }
641*6a54128fSAndroid Build Coastguard Worker
642*6a54128fSAndroid Build Coastguard Worker
643*6a54128fSAndroid Build Coastguard Worker //
644*6a54128fSAndroid Build Coastguard Worker // forms: hda[n], fd[n]
645*6a54128fSAndroid Build Coastguard Worker //
646*6a54128fSAndroid Build Coastguard Worker
647*6a54128fSAndroid Build Coastguard Worker if('d' != *(Device + 1))
648*6a54128fSAndroid Build Coastguard Worker {
649*6a54128fSAndroid Build Coastguard Worker return NULL;
650*6a54128fSAndroid Build Coastguard Worker }
651*6a54128fSAndroid Build Coastguard Worker
652*6a54128fSAndroid Build Coastguard Worker if('h' == *Device)
653*6a54128fSAndroid Build Coastguard Worker {
654*6a54128fSAndroid Build Coastguard Worker if((*(Device + 2) < 'a') || (*(Device + 2) > ('a' + 9)) ||
655*6a54128fSAndroid Build Coastguard Worker ((*(Device + 3) != '\0') &&
656*6a54128fSAndroid Build Coastguard Worker ((*(Device + 4) != '\0') ||
657*6a54128fSAndroid Build Coastguard Worker ((*(Device + 3) < '0') || (*(Device + 3) > '9'))
658*6a54128fSAndroid Build Coastguard Worker )
659*6a54128fSAndroid Build Coastguard Worker )
660*6a54128fSAndroid Build Coastguard Worker )
661*6a54128fSAndroid Build Coastguard Worker {
662*6a54128fSAndroid Build Coastguard Worker return NULL;
663*6a54128fSAndroid Build Coastguard Worker }
664*6a54128fSAndroid Build Coastguard Worker
665*6a54128fSAndroid Build Coastguard Worker DiskNumber = (UCHAR)(*(Device + 2) - 'a');
666*6a54128fSAndroid Build Coastguard Worker
667*6a54128fSAndroid Build Coastguard Worker if(*(Device + 3) != '\0')
668*6a54128fSAndroid Build Coastguard Worker {
669*6a54128fSAndroid Build Coastguard Worker PartitionNumber = (*(Device + 3) - '0');
670*6a54128fSAndroid Build Coastguard Worker }
671*6a54128fSAndroid Build Coastguard Worker
672*6a54128fSAndroid Build Coastguard Worker }
673*6a54128fSAndroid Build Coastguard Worker else if('f' == *Device)
674*6a54128fSAndroid Build Coastguard Worker {
675*6a54128fSAndroid Build Coastguard Worker //
676*6a54128fSAndroid Build Coastguard Worker // 3-d letter should be a digit.
677*6a54128fSAndroid Build Coastguard Worker //
678*6a54128fSAndroid Build Coastguard Worker
679*6a54128fSAndroid Build Coastguard Worker if((*(Device + 3) != '\0') ||
680*6a54128fSAndroid Build Coastguard Worker (*(Device + 2) < '0') || (*(Device + 2) > '9'))
681*6a54128fSAndroid Build Coastguard Worker {
682*6a54128fSAndroid Build Coastguard Worker return NULL;
683*6a54128fSAndroid Build Coastguard Worker }
684*6a54128fSAndroid Build Coastguard Worker
685*6a54128fSAndroid Build Coastguard Worker DiskNumber = (UCHAR)(*(Device + 2) - '0');
686*6a54128fSAndroid Build Coastguard Worker
687*6a54128fSAndroid Build Coastguard Worker }
688*6a54128fSAndroid Build Coastguard Worker else
689*6a54128fSAndroid Build Coastguard Worker {
690*6a54128fSAndroid Build Coastguard Worker //
691*6a54128fSAndroid Build Coastguard Worker // invalid prefix
692*6a54128fSAndroid Build Coastguard Worker //
693*6a54128fSAndroid Build Coastguard Worker
694*6a54128fSAndroid Build Coastguard Worker return NULL;
695*6a54128fSAndroid Build Coastguard Worker }
696*6a54128fSAndroid Build Coastguard Worker
697*6a54128fSAndroid Build Coastguard Worker
698*6a54128fSAndroid Build Coastguard Worker
699*6a54128fSAndroid Build Coastguard Worker //
700*6a54128fSAndroid Build Coastguard Worker // Prefix
701*6a54128fSAndroid Build Coastguard Worker //
702*6a54128fSAndroid Build Coastguard Worker
703*6a54128fSAndroid Build Coastguard Worker strcpy(NormalizedDeviceNameBuffer, "\\Device\\");
704*6a54128fSAndroid Build Coastguard Worker
705*6a54128fSAndroid Build Coastguard Worker //
706*6a54128fSAndroid Build Coastguard Worker // Media name
707*6a54128fSAndroid Build Coastguard Worker //
708*6a54128fSAndroid Build Coastguard Worker
709*6a54128fSAndroid Build Coastguard Worker switch(*Device)
710*6a54128fSAndroid Build Coastguard Worker {
711*6a54128fSAndroid Build Coastguard Worker
712*6a54128fSAndroid Build Coastguard Worker case 'f':
713*6a54128fSAndroid Build Coastguard Worker strcat(NormalizedDeviceNameBuffer, "Floppy0");
714*6a54128fSAndroid Build Coastguard Worker break;
715*6a54128fSAndroid Build Coastguard Worker
716*6a54128fSAndroid Build Coastguard Worker case 'h':
717*6a54128fSAndroid Build Coastguard Worker strcat(NormalizedDeviceNameBuffer, "Harddisk0");
718*6a54128fSAndroid Build Coastguard Worker break;
719*6a54128fSAndroid Build Coastguard Worker }
720*6a54128fSAndroid Build Coastguard Worker
721*6a54128fSAndroid Build Coastguard Worker
722*6a54128fSAndroid Build Coastguard Worker p = NormalizedDeviceNameBuffer + strlen(NormalizedDeviceNameBuffer) - 1;
723*6a54128fSAndroid Build Coastguard Worker *p = (CHAR)(*p + DiskNumber);
724*6a54128fSAndroid Build Coastguard Worker
725*6a54128fSAndroid Build Coastguard Worker
726*6a54128fSAndroid Build Coastguard Worker //
727*6a54128fSAndroid Build Coastguard Worker // Partition nr.
728*6a54128fSAndroid Build Coastguard Worker //
729*6a54128fSAndroid Build Coastguard Worker
730*6a54128fSAndroid Build Coastguard Worker if(PartitionNumber >= 0)
731*6a54128fSAndroid Build Coastguard Worker {
732*6a54128fSAndroid Build Coastguard Worker strcat(NormalizedDeviceNameBuffer, "\\Partition0");
733*6a54128fSAndroid Build Coastguard Worker
734*6a54128fSAndroid Build Coastguard Worker p = NormalizedDeviceNameBuffer + strlen(NormalizedDeviceNameBuffer) - 1;
735*6a54128fSAndroid Build Coastguard Worker *p = (CHAR)(*p + PartitionNumber);
736*6a54128fSAndroid Build Coastguard Worker }
737*6a54128fSAndroid Build Coastguard Worker
738*6a54128fSAndroid Build Coastguard Worker
739*6a54128fSAndroid Build Coastguard Worker return NormalizedDeviceNameBuffer;
740*6a54128fSAndroid Build Coastguard Worker }
741*6a54128fSAndroid Build Coastguard Worker
742*6a54128fSAndroid Build Coastguard Worker
743*6a54128fSAndroid Build Coastguard Worker
744*6a54128fSAndroid Build Coastguard Worker
745*6a54128fSAndroid Build Coastguard Worker static
746*6a54128fSAndroid Build Coastguard Worker VOID
_GetDeviceSize(IN HANDLE h,OUT unsigned __int64 * FsSize)747*6a54128fSAndroid Build Coastguard Worker _GetDeviceSize(
748*6a54128fSAndroid Build Coastguard Worker IN HANDLE h,
749*6a54128fSAndroid Build Coastguard Worker OUT unsigned __int64 *FsSize
750*6a54128fSAndroid Build Coastguard Worker )
751*6a54128fSAndroid Build Coastguard Worker {
752*6a54128fSAndroid Build Coastguard Worker PARTITION_INFORMATION pi;
753*6a54128fSAndroid Build Coastguard Worker DISK_GEOMETRY gi;
754*6a54128fSAndroid Build Coastguard Worker NTSTATUS Status;
755*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
756*6a54128fSAndroid Build Coastguard Worker
757*6a54128fSAndroid Build Coastguard Worker //
758*6a54128fSAndroid Build Coastguard Worker // Zero it
759*6a54128fSAndroid Build Coastguard Worker //
760*6a54128fSAndroid Build Coastguard Worker
761*6a54128fSAndroid Build Coastguard Worker *FsSize = 0;
762*6a54128fSAndroid Build Coastguard Worker
763*6a54128fSAndroid Build Coastguard Worker //
764*6a54128fSAndroid Build Coastguard Worker // Call driver
765*6a54128fSAndroid Build Coastguard Worker //
766*6a54128fSAndroid Build Coastguard Worker
767*6a54128fSAndroid Build Coastguard Worker RtlZeroMemory(&pi, sizeof(PARTITION_INFORMATION));
768*6a54128fSAndroid Build Coastguard Worker
769*6a54128fSAndroid Build Coastguard Worker Status = NtDeviceIoControlFile(
770*6a54128fSAndroid Build Coastguard Worker h, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_PARTITION_INFO,
771*6a54128fSAndroid Build Coastguard Worker &pi, sizeof(PARTITION_INFORMATION),
772*6a54128fSAndroid Build Coastguard Worker &pi, sizeof(PARTITION_INFORMATION));
773*6a54128fSAndroid Build Coastguard Worker
774*6a54128fSAndroid Build Coastguard Worker
775*6a54128fSAndroid Build Coastguard Worker if(NT_SUCCESS(Status))
776*6a54128fSAndroid Build Coastguard Worker {
777*6a54128fSAndroid Build Coastguard Worker *FsSize = pi.PartitionLength.QuadPart;
778*6a54128fSAndroid Build Coastguard Worker }
779*6a54128fSAndroid Build Coastguard Worker else if(STATUS_INVALID_DEVICE_REQUEST == Status)
780*6a54128fSAndroid Build Coastguard Worker {
781*6a54128fSAndroid Build Coastguard Worker //
782*6a54128fSAndroid Build Coastguard Worker // No partitions: get device info.
783*6a54128fSAndroid Build Coastguard Worker //
784*6a54128fSAndroid Build Coastguard Worker
785*6a54128fSAndroid Build Coastguard Worker RtlZeroMemory(&gi, sizeof(DISK_GEOMETRY));
786*6a54128fSAndroid Build Coastguard Worker
787*6a54128fSAndroid Build Coastguard Worker Status = NtDeviceIoControlFile(
788*6a54128fSAndroid Build Coastguard Worker h, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_DRIVE_GEOMETRY,
789*6a54128fSAndroid Build Coastguard Worker &gi, sizeof(DISK_GEOMETRY),
790*6a54128fSAndroid Build Coastguard Worker &gi, sizeof(DISK_GEOMETRY));
791*6a54128fSAndroid Build Coastguard Worker
792*6a54128fSAndroid Build Coastguard Worker
793*6a54128fSAndroid Build Coastguard Worker if(NT_SUCCESS(Status))
794*6a54128fSAndroid Build Coastguard Worker {
795*6a54128fSAndroid Build Coastguard Worker *FsSize =
796*6a54128fSAndroid Build Coastguard Worker gi.BytesPerSector *
797*6a54128fSAndroid Build Coastguard Worker gi.SectorsPerTrack *
798*6a54128fSAndroid Build Coastguard Worker gi.TracksPerCylinder *
799*6a54128fSAndroid Build Coastguard Worker gi.Cylinders.QuadPart;
800*6a54128fSAndroid Build Coastguard Worker }
801*6a54128fSAndroid Build Coastguard Worker
802*6a54128fSAndroid Build Coastguard Worker }
803*6a54128fSAndroid Build Coastguard Worker }
804*6a54128fSAndroid Build Coastguard Worker
805*6a54128fSAndroid Build Coastguard Worker
806*6a54128fSAndroid Build Coastguard Worker
807*6a54128fSAndroid Build Coastguard Worker //
808*6a54128fSAndroid Build Coastguard Worker // Open device by name.
809*6a54128fSAndroid Build Coastguard Worker //
810*6a54128fSAndroid Build Coastguard Worker
811*6a54128fSAndroid Build Coastguard Worker static
812*6a54128fSAndroid Build Coastguard Worker BOOLEAN
_Ext2OpenDevice(IN PCSTR Name,IN BOOLEAN ReadOnly,OUT PHANDLE Handle,OUT PBOOLEAN OpenedReadonly OPTIONAL,OUT unsigned * Errno OPTIONAL)813*6a54128fSAndroid Build Coastguard Worker _Ext2OpenDevice(
814*6a54128fSAndroid Build Coastguard Worker IN PCSTR Name,
815*6a54128fSAndroid Build Coastguard Worker IN BOOLEAN ReadOnly,
816*6a54128fSAndroid Build Coastguard Worker OUT PHANDLE Handle,
817*6a54128fSAndroid Build Coastguard Worker OUT PBOOLEAN OpenedReadonly OPTIONAL,
818*6a54128fSAndroid Build Coastguard Worker OUT unsigned *Errno OPTIONAL
819*6a54128fSAndroid Build Coastguard Worker )
820*6a54128fSAndroid Build Coastguard Worker {
821*6a54128fSAndroid Build Coastguard Worker CHAR NormalizedDeviceName[512];
822*6a54128fSAndroid Build Coastguard Worker NTSTATUS Status;
823*6a54128fSAndroid Build Coastguard Worker
824*6a54128fSAndroid Build Coastguard Worker if(NULL == Name)
825*6a54128fSAndroid Build Coastguard Worker {
826*6a54128fSAndroid Build Coastguard Worker //
827*6a54128fSAndroid Build Coastguard Worker // Set not found
828*6a54128fSAndroid Build Coastguard Worker //
829*6a54128fSAndroid Build Coastguard Worker
830*6a54128fSAndroid Build Coastguard Worker if(ARGUMENT_PRESENT(Errno))
831*6a54128fSAndroid Build Coastguard Worker *Errno = ENOENT;
832*6a54128fSAndroid Build Coastguard Worker
833*6a54128fSAndroid Build Coastguard Worker return FALSE;
834*6a54128fSAndroid Build Coastguard Worker }
835*6a54128fSAndroid Build Coastguard Worker
836*6a54128fSAndroid Build Coastguard Worker
837*6a54128fSAndroid Build Coastguard Worker if((((*Name) | 0x20) >= 'a') && (((*Name) | 0x20) <= 'z') &&
838*6a54128fSAndroid Build Coastguard Worker (':' == *(Name + 1)) && ('\0' == *(Name + 2)))
839*6a54128fSAndroid Build Coastguard Worker {
840*6a54128fSAndroid Build Coastguard Worker Status = _OpenDriveLetter(*Name, ReadOnly, Handle, OpenedReadonly);
841*6a54128fSAndroid Build Coastguard Worker }
842*6a54128fSAndroid Build Coastguard Worker else
843*6a54128fSAndroid Build Coastguard Worker {
844*6a54128fSAndroid Build Coastguard Worker //
845*6a54128fSAndroid Build Coastguard Worker // Make name
846*6a54128fSAndroid Build Coastguard Worker //
847*6a54128fSAndroid Build Coastguard Worker
848*6a54128fSAndroid Build Coastguard Worker Name = _NormalizeDeviceName(Name, NormalizedDeviceName);
849*6a54128fSAndroid Build Coastguard Worker
850*6a54128fSAndroid Build Coastguard Worker if(NULL == Name)
851*6a54128fSAndroid Build Coastguard Worker {
852*6a54128fSAndroid Build Coastguard Worker //
853*6a54128fSAndroid Build Coastguard Worker // Set not found
854*6a54128fSAndroid Build Coastguard Worker //
855*6a54128fSAndroid Build Coastguard Worker
856*6a54128fSAndroid Build Coastguard Worker if(ARGUMENT_PRESENT(Errno))
857*6a54128fSAndroid Build Coastguard Worker *Errno = ENOENT;
858*6a54128fSAndroid Build Coastguard Worker
859*6a54128fSAndroid Build Coastguard Worker return FALSE;
860*6a54128fSAndroid Build Coastguard Worker }
861*6a54128fSAndroid Build Coastguard Worker
862*6a54128fSAndroid Build Coastguard Worker //
863*6a54128fSAndroid Build Coastguard Worker // Try to open it
864*6a54128fSAndroid Build Coastguard Worker //
865*6a54128fSAndroid Build Coastguard Worker
866*6a54128fSAndroid Build Coastguard Worker Status = _OpenNtName(Name, ReadOnly, Handle, OpenedReadonly);
867*6a54128fSAndroid Build Coastguard Worker }
868*6a54128fSAndroid Build Coastguard Worker
869*6a54128fSAndroid Build Coastguard Worker
870*6a54128fSAndroid Build Coastguard Worker if(!NT_SUCCESS(Status))
871*6a54128fSAndroid Build Coastguard Worker {
872*6a54128fSAndroid Build Coastguard Worker if(ARGUMENT_PRESENT(Errno))
873*6a54128fSAndroid Build Coastguard Worker *Errno = _MapNtStatus(Status);
874*6a54128fSAndroid Build Coastguard Worker
875*6a54128fSAndroid Build Coastguard Worker return FALSE;
876*6a54128fSAndroid Build Coastguard Worker }
877*6a54128fSAndroid Build Coastguard Worker
878*6a54128fSAndroid Build Coastguard Worker return TRUE;
879*6a54128fSAndroid Build Coastguard Worker }
880*6a54128fSAndroid Build Coastguard Worker
881*6a54128fSAndroid Build Coastguard Worker
882*6a54128fSAndroid Build Coastguard Worker //
883*6a54128fSAndroid Build Coastguard Worker // Raw block io. Sets dos errno
884*6a54128fSAndroid Build Coastguard Worker //
885*6a54128fSAndroid Build Coastguard Worker
886*6a54128fSAndroid Build Coastguard Worker static
887*6a54128fSAndroid Build Coastguard Worker BOOLEAN
_BlockIo(IN HANDLE Handle,IN LARGE_INTEGER Offset,IN ULONG Bytes,IN OUT PCHAR Buffer,IN BOOLEAN Read,OUT unsigned * Errno)888*6a54128fSAndroid Build Coastguard Worker _BlockIo(
889*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle,
890*6a54128fSAndroid Build Coastguard Worker IN LARGE_INTEGER Offset,
891*6a54128fSAndroid Build Coastguard Worker IN ULONG Bytes,
892*6a54128fSAndroid Build Coastguard Worker IN OUT PCHAR Buffer,
893*6a54128fSAndroid Build Coastguard Worker IN BOOLEAN Read,
894*6a54128fSAndroid Build Coastguard Worker OUT unsigned* Errno
895*6a54128fSAndroid Build Coastguard Worker )
896*6a54128fSAndroid Build Coastguard Worker {
897*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
898*6a54128fSAndroid Build Coastguard Worker NTSTATUS Status;
899*6a54128fSAndroid Build Coastguard Worker
900*6a54128fSAndroid Build Coastguard Worker //
901*6a54128fSAndroid Build Coastguard Worker // Should be aligned
902*6a54128fSAndroid Build Coastguard Worker //
903*6a54128fSAndroid Build Coastguard Worker
904*6a54128fSAndroid Build Coastguard Worker ASSERT(0 == (Bytes % 512));
905*6a54128fSAndroid Build Coastguard Worker ASSERT(0 == (Offset.LowPart % 512));
906*6a54128fSAndroid Build Coastguard Worker
907*6a54128fSAndroid Build Coastguard Worker
908*6a54128fSAndroid Build Coastguard Worker //
909*6a54128fSAndroid Build Coastguard Worker // perform io
910*6a54128fSAndroid Build Coastguard Worker //
911*6a54128fSAndroid Build Coastguard Worker
912*6a54128fSAndroid Build Coastguard Worker if(Read)
913*6a54128fSAndroid Build Coastguard Worker {
914*6a54128fSAndroid Build Coastguard Worker Status = NtReadFile(Handle, NULL, NULL, NULL,
915*6a54128fSAndroid Build Coastguard Worker &IoStatusBlock, Buffer, Bytes, &Offset, NULL);
916*6a54128fSAndroid Build Coastguard Worker }
917*6a54128fSAndroid Build Coastguard Worker else
918*6a54128fSAndroid Build Coastguard Worker {
919*6a54128fSAndroid Build Coastguard Worker Status = NtWriteFile(Handle, NULL, NULL, NULL,
920*6a54128fSAndroid Build Coastguard Worker &IoStatusBlock, Buffer, Bytes, &Offset, NULL);
921*6a54128fSAndroid Build Coastguard Worker }
922*6a54128fSAndroid Build Coastguard Worker
923*6a54128fSAndroid Build Coastguard Worker
924*6a54128fSAndroid Build Coastguard Worker //
925*6a54128fSAndroid Build Coastguard Worker // translate error
926*6a54128fSAndroid Build Coastguard Worker //
927*6a54128fSAndroid Build Coastguard Worker
928*6a54128fSAndroid Build Coastguard Worker if(NT_SUCCESS(Status))
929*6a54128fSAndroid Build Coastguard Worker {
930*6a54128fSAndroid Build Coastguard Worker *Errno = 0;
931*6a54128fSAndroid Build Coastguard Worker return TRUE;
932*6a54128fSAndroid Build Coastguard Worker }
933*6a54128fSAndroid Build Coastguard Worker
934*6a54128fSAndroid Build Coastguard Worker *Errno = _MapNtStatus(Status);
935*6a54128fSAndroid Build Coastguard Worker
936*6a54128fSAndroid Build Coastguard Worker return FALSE;
937*6a54128fSAndroid Build Coastguard Worker }
938*6a54128fSAndroid Build Coastguard Worker
939*6a54128fSAndroid Build Coastguard Worker
940*6a54128fSAndroid Build Coastguard Worker
941*6a54128fSAndroid Build Coastguard Worker __inline
942*6a54128fSAndroid Build Coastguard Worker BOOLEAN
_RawWrite(IN HANDLE Handle,IN LARGE_INTEGER Offset,IN ULONG Bytes,OUT const CHAR * Buffer,OUT unsigned * Errno)943*6a54128fSAndroid Build Coastguard Worker _RawWrite(
944*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle,
945*6a54128fSAndroid Build Coastguard Worker IN LARGE_INTEGER Offset,
946*6a54128fSAndroid Build Coastguard Worker IN ULONG Bytes,
947*6a54128fSAndroid Build Coastguard Worker OUT const CHAR* Buffer,
948*6a54128fSAndroid Build Coastguard Worker OUT unsigned* Errno
949*6a54128fSAndroid Build Coastguard Worker )
950*6a54128fSAndroid Build Coastguard Worker {
951*6a54128fSAndroid Build Coastguard Worker return _BlockIo(Handle, Offset, Bytes, (PCHAR)Buffer, FALSE, Errno);
952*6a54128fSAndroid Build Coastguard Worker }
953*6a54128fSAndroid Build Coastguard Worker
954*6a54128fSAndroid Build Coastguard Worker __inline
955*6a54128fSAndroid Build Coastguard Worker BOOLEAN
_RawRead(IN HANDLE Handle,IN LARGE_INTEGER Offset,IN ULONG Bytes,IN PCHAR Buffer,OUT unsigned * Errno)956*6a54128fSAndroid Build Coastguard Worker _RawRead(
957*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle,
958*6a54128fSAndroid Build Coastguard Worker IN LARGE_INTEGER Offset,
959*6a54128fSAndroid Build Coastguard Worker IN ULONG Bytes,
960*6a54128fSAndroid Build Coastguard Worker IN PCHAR Buffer,
961*6a54128fSAndroid Build Coastguard Worker OUT unsigned* Errno
962*6a54128fSAndroid Build Coastguard Worker )
963*6a54128fSAndroid Build Coastguard Worker {
964*6a54128fSAndroid Build Coastguard Worker return _BlockIo(Handle, Offset, Bytes, Buffer, TRUE, Errno);
965*6a54128fSAndroid Build Coastguard Worker }
966*6a54128fSAndroid Build Coastguard Worker
967*6a54128fSAndroid Build Coastguard Worker
968*6a54128fSAndroid Build Coastguard Worker
969*6a54128fSAndroid Build Coastguard Worker __inline
970*6a54128fSAndroid Build Coastguard Worker BOOLEAN
_SetPartType(IN HANDLE Handle,IN UCHAR Type)971*6a54128fSAndroid Build Coastguard Worker _SetPartType(
972*6a54128fSAndroid Build Coastguard Worker IN HANDLE Handle,
973*6a54128fSAndroid Build Coastguard Worker IN UCHAR Type
974*6a54128fSAndroid Build Coastguard Worker )
975*6a54128fSAndroid Build Coastguard Worker {
976*6a54128fSAndroid Build Coastguard Worker IO_STATUS_BLOCK IoStatusBlock;
977*6a54128fSAndroid Build Coastguard Worker return STATUS_SUCCESS == NtDeviceIoControlFile(
978*6a54128fSAndroid Build Coastguard Worker Handle, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_SET_PARTITION_INFO,
979*6a54128fSAndroid Build Coastguard Worker &Type, sizeof(Type),
980*6a54128fSAndroid Build Coastguard Worker NULL, 0);
981*6a54128fSAndroid Build Coastguard Worker }
982*6a54128fSAndroid Build Coastguard Worker
983*6a54128fSAndroid Build Coastguard Worker
984*6a54128fSAndroid Build Coastguard Worker
985*6a54128fSAndroid Build Coastguard Worker //--------------------- interface part
986*6a54128fSAndroid Build Coastguard Worker
987*6a54128fSAndroid Build Coastguard Worker //
988*6a54128fSAndroid Build Coastguard Worker // Interface functions.
989*6a54128fSAndroid Build Coastguard Worker // Is_mounted is set to 1 if the device is mounted, 0 otherwise
990*6a54128fSAndroid Build Coastguard Worker //
991*6a54128fSAndroid Build Coastguard Worker
992*6a54128fSAndroid Build Coastguard Worker errcode_t
ext2fs_check_if_mounted(const char * file,int * mount_flags)993*6a54128fSAndroid Build Coastguard Worker ext2fs_check_if_mounted(const char *file, int *mount_flags)
994*6a54128fSAndroid Build Coastguard Worker {
995*6a54128fSAndroid Build Coastguard Worker HANDLE h;
996*6a54128fSAndroid Build Coastguard Worker BOOLEAN Readonly;
997*6a54128fSAndroid Build Coastguard Worker
998*6a54128fSAndroid Build Coastguard Worker *mount_flags = 0;
999*6a54128fSAndroid Build Coastguard Worker
1000*6a54128fSAndroid Build Coastguard Worker if(!_Ext2OpenDevice(file, TRUE, &h, &Readonly, NULL))
1001*6a54128fSAndroid Build Coastguard Worker {
1002*6a54128fSAndroid Build Coastguard Worker return 0;
1003*6a54128fSAndroid Build Coastguard Worker }
1004*6a54128fSAndroid Build Coastguard Worker
1005*6a54128fSAndroid Build Coastguard Worker
1006*6a54128fSAndroid Build Coastguard Worker __try{
1007*6a54128fSAndroid Build Coastguard Worker *mount_flags &= _IsMounted(h) ? EXT2_MF_MOUNTED : 0;
1008*6a54128fSAndroid Build Coastguard Worker }
1009*6a54128fSAndroid Build Coastguard Worker __finally{
1010*6a54128fSAndroid Build Coastguard Worker _CloseDisk(h);
1011*6a54128fSAndroid Build Coastguard Worker }
1012*6a54128fSAndroid Build Coastguard Worker
1013*6a54128fSAndroid Build Coastguard Worker return 0;
1014*6a54128fSAndroid Build Coastguard Worker }
1015*6a54128fSAndroid Build Coastguard Worker
1016*6a54128fSAndroid Build Coastguard Worker
1017*6a54128fSAndroid Build Coastguard Worker
1018*6a54128fSAndroid Build Coastguard Worker //
1019*6a54128fSAndroid Build Coastguard Worker // Returns the number of blocks in a partition
1020*6a54128fSAndroid Build Coastguard Worker //
1021*6a54128fSAndroid Build Coastguard Worker
1022*6a54128fSAndroid Build Coastguard Worker static __int64 FsSize = 0;
1023*6a54128fSAndroid Build Coastguard Worker static char knowndevice[1024] = "";
1024*6a54128fSAndroid Build Coastguard Worker
1025*6a54128fSAndroid Build Coastguard Worker
1026*6a54128fSAndroid Build Coastguard Worker errcode_t
ext2fs_get_device_size(const char * file,int blocksize,blk_t * retblocks)1027*6a54128fSAndroid Build Coastguard Worker ext2fs_get_device_size(const char *file, int blocksize,
1028*6a54128fSAndroid Build Coastguard Worker blk_t *retblocks)
1029*6a54128fSAndroid Build Coastguard Worker {
1030*6a54128fSAndroid Build Coastguard Worker HANDLE h;
1031*6a54128fSAndroid Build Coastguard Worker BOOLEAN Readonly;
1032*6a54128fSAndroid Build Coastguard Worker
1033*6a54128fSAndroid Build Coastguard Worker if((0 == FsSize) || (0 != strcmp(knowndevice, file)))
1034*6a54128fSAndroid Build Coastguard Worker {
1035*6a54128fSAndroid Build Coastguard Worker
1036*6a54128fSAndroid Build Coastguard Worker if(!_Ext2OpenDevice(file, TRUE, &h, &Readonly, NULL))
1037*6a54128fSAndroid Build Coastguard Worker {
1038*6a54128fSAndroid Build Coastguard Worker return 0;
1039*6a54128fSAndroid Build Coastguard Worker }
1040*6a54128fSAndroid Build Coastguard Worker
1041*6a54128fSAndroid Build Coastguard Worker
1042*6a54128fSAndroid Build Coastguard Worker __try{
1043*6a54128fSAndroid Build Coastguard Worker
1044*6a54128fSAndroid Build Coastguard Worker //
1045*6a54128fSAndroid Build Coastguard Worker // Get size
1046*6a54128fSAndroid Build Coastguard Worker //
1047*6a54128fSAndroid Build Coastguard Worker
1048*6a54128fSAndroid Build Coastguard Worker _GetDeviceSize(h, &FsSize);
1049*6a54128fSAndroid Build Coastguard Worker strcpy(knowndevice, file);
1050*6a54128fSAndroid Build Coastguard Worker }
1051*6a54128fSAndroid Build Coastguard Worker __finally{
1052*6a54128fSAndroid Build Coastguard Worker _CloseDisk(h);
1053*6a54128fSAndroid Build Coastguard Worker }
1054*6a54128fSAndroid Build Coastguard Worker
1055*6a54128fSAndroid Build Coastguard Worker }
1056*6a54128fSAndroid Build Coastguard Worker
1057*6a54128fSAndroid Build Coastguard Worker *retblocks = (blk_t)(unsigned __int64)(FsSize / blocksize);
1058*6a54128fSAndroid Build Coastguard Worker UNREFERENCED_PARAMETER(file);
1059*6a54128fSAndroid Build Coastguard Worker return 0;
1060*6a54128fSAndroid Build Coastguard Worker }
1061*6a54128fSAndroid Build Coastguard Worker
1062*6a54128fSAndroid Build Coastguard Worker
1063*6a54128fSAndroid Build Coastguard Worker
1064*6a54128fSAndroid Build Coastguard Worker
1065*6a54128fSAndroid Build Coastguard Worker
1066*6a54128fSAndroid Build Coastguard Worker
1067*6a54128fSAndroid Build Coastguard Worker //
1068*6a54128fSAndroid Build Coastguard Worker // Table elements
1069*6a54128fSAndroid Build Coastguard Worker //
1070*6a54128fSAndroid Build Coastguard Worker
1071*6a54128fSAndroid Build Coastguard Worker
1072*6a54128fSAndroid Build Coastguard Worker static
1073*6a54128fSAndroid Build Coastguard Worker errcode_t
nt_open(const char * name,int flags,io_channel * channel)1074*6a54128fSAndroid Build Coastguard Worker nt_open(const char *name, int flags, io_channel *channel)
1075*6a54128fSAndroid Build Coastguard Worker {
1076*6a54128fSAndroid Build Coastguard Worker io_channel io = NULL;
1077*6a54128fSAndroid Build Coastguard Worker PNT_PRIVATE_DATA NtData = NULL;
1078*6a54128fSAndroid Build Coastguard Worker errcode_t Errno = 0;
1079*6a54128fSAndroid Build Coastguard Worker
1080*6a54128fSAndroid Build Coastguard Worker //
1081*6a54128fSAndroid Build Coastguard Worker // Check name
1082*6a54128fSAndroid Build Coastguard Worker //
1083*6a54128fSAndroid Build Coastguard Worker
1084*6a54128fSAndroid Build Coastguard Worker if (NULL == name)
1085*6a54128fSAndroid Build Coastguard Worker {
1086*6a54128fSAndroid Build Coastguard Worker return EXT2_ET_BAD_DEVICE_NAME;
1087*6a54128fSAndroid Build Coastguard Worker }
1088*6a54128fSAndroid Build Coastguard Worker
1089*6a54128fSAndroid Build Coastguard Worker __try{
1090*6a54128fSAndroid Build Coastguard Worker
1091*6a54128fSAndroid Build Coastguard Worker //
1092*6a54128fSAndroid Build Coastguard Worker // Allocate channel handle
1093*6a54128fSAndroid Build Coastguard Worker //
1094*6a54128fSAndroid Build Coastguard Worker
1095*6a54128fSAndroid Build Coastguard Worker io = (io_channel) malloc(sizeof(struct struct_io_channel));
1096*6a54128fSAndroid Build Coastguard Worker
1097*6a54128fSAndroid Build Coastguard Worker if (NULL == io)
1098*6a54128fSAndroid Build Coastguard Worker {
1099*6a54128fSAndroid Build Coastguard Worker Errno = ENOMEM;
1100*6a54128fSAndroid Build Coastguard Worker __leave;
1101*6a54128fSAndroid Build Coastguard Worker }
1102*6a54128fSAndroid Build Coastguard Worker
1103*6a54128fSAndroid Build Coastguard Worker RtlZeroMemory(io, sizeof(struct struct_io_channel));
1104*6a54128fSAndroid Build Coastguard Worker io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
1105*6a54128fSAndroid Build Coastguard Worker
1106*6a54128fSAndroid Build Coastguard Worker NtData = (PNT_PRIVATE_DATA)malloc(sizeof(NT_PRIVATE_DATA));
1107*6a54128fSAndroid Build Coastguard Worker
1108*6a54128fSAndroid Build Coastguard Worker if (NULL == NtData)
1109*6a54128fSAndroid Build Coastguard Worker {
1110*6a54128fSAndroid Build Coastguard Worker Errno = ENOMEM;
1111*6a54128fSAndroid Build Coastguard Worker __leave;
1112*6a54128fSAndroid Build Coastguard Worker }
1113*6a54128fSAndroid Build Coastguard Worker
1114*6a54128fSAndroid Build Coastguard Worker
1115*6a54128fSAndroid Build Coastguard Worker io->manager = nt_io_manager();
1116*6a54128fSAndroid Build Coastguard Worker io->name = malloc(strlen(name) + 1);
1117*6a54128fSAndroid Build Coastguard Worker if (NULL == io->name)
1118*6a54128fSAndroid Build Coastguard Worker {
1119*6a54128fSAndroid Build Coastguard Worker Errno = ENOMEM;
1120*6a54128fSAndroid Build Coastguard Worker __leave;
1121*6a54128fSAndroid Build Coastguard Worker }
1122*6a54128fSAndroid Build Coastguard Worker
1123*6a54128fSAndroid Build Coastguard Worker strcpy(io->name, name);
1124*6a54128fSAndroid Build Coastguard Worker io->private_data = NtData;
1125*6a54128fSAndroid Build Coastguard Worker io->block_size = 1024;
1126*6a54128fSAndroid Build Coastguard Worker io->read_error = 0;
1127*6a54128fSAndroid Build Coastguard Worker io->write_error = 0;
1128*6a54128fSAndroid Build Coastguard Worker io->refcount = 1;
1129*6a54128fSAndroid Build Coastguard Worker
1130*6a54128fSAndroid Build Coastguard Worker //
1131*6a54128fSAndroid Build Coastguard Worker // Initialize data
1132*6a54128fSAndroid Build Coastguard Worker //
1133*6a54128fSAndroid Build Coastguard Worker
1134*6a54128fSAndroid Build Coastguard Worker RtlZeroMemory(NtData, sizeof(NT_PRIVATE_DATA));
1135*6a54128fSAndroid Build Coastguard Worker
1136*6a54128fSAndroid Build Coastguard Worker NtData->magic = EXT2_ET_MAGIC_NT_IO_CHANNEL;
1137*6a54128fSAndroid Build Coastguard Worker NtData->BufferBlockNumber = 0xffffffff;
1138*6a54128fSAndroid Build Coastguard Worker NtData->BufferSize = 1024;
1139*6a54128fSAndroid Build Coastguard Worker NtData->Buffer = malloc(NtData->BufferSize);
1140*6a54128fSAndroid Build Coastguard Worker
1141*6a54128fSAndroid Build Coastguard Worker if (NULL == NtData->Buffer)
1142*6a54128fSAndroid Build Coastguard Worker {
1143*6a54128fSAndroid Build Coastguard Worker Errno = ENOMEM;
1144*6a54128fSAndroid Build Coastguard Worker __leave;
1145*6a54128fSAndroid Build Coastguard Worker }
1146*6a54128fSAndroid Build Coastguard Worker
1147*6a54128fSAndroid Build Coastguard Worker //
1148*6a54128fSAndroid Build Coastguard Worker // Open it
1149*6a54128fSAndroid Build Coastguard Worker //
1150*6a54128fSAndroid Build Coastguard Worker
1151*6a54128fSAndroid Build Coastguard Worker if(!_Ext2OpenDevice(name, (BOOLEAN)!BooleanFlagOn(flags, EXT2_FLAG_RW), &NtData->Handle, &NtData->OpenedReadonly, &Errno))
1152*6a54128fSAndroid Build Coastguard Worker {
1153*6a54128fSAndroid Build Coastguard Worker __leave;
1154*6a54128fSAndroid Build Coastguard Worker }
1155*6a54128fSAndroid Build Coastguard Worker
1156*6a54128fSAndroid Build Coastguard Worker
1157*6a54128fSAndroid Build Coastguard Worker //
1158*6a54128fSAndroid Build Coastguard Worker // get size
1159*6a54128fSAndroid Build Coastguard Worker //
1160*6a54128fSAndroid Build Coastguard Worker
1161*6a54128fSAndroid Build Coastguard Worker _GetDeviceSize(NtData->Handle, &FsSize);
1162*6a54128fSAndroid Build Coastguard Worker strcpy(knowndevice, name);
1163*6a54128fSAndroid Build Coastguard Worker
1164*6a54128fSAndroid Build Coastguard Worker
1165*6a54128fSAndroid Build Coastguard Worker //
1166*6a54128fSAndroid Build Coastguard Worker // Lock/dismount
1167*6a54128fSAndroid Build Coastguard Worker //
1168*6a54128fSAndroid Build Coastguard Worker
1169*6a54128fSAndroid Build Coastguard Worker if(!NT_SUCCESS(_LockDrive(NtData->Handle)) /*|| !NT_SUCCESS(_DismountDrive(NtData->Handle))*/)
1170*6a54128fSAndroid Build Coastguard Worker {
1171*6a54128fSAndroid Build Coastguard Worker NtData->OpenedReadonly = TRUE;
1172*6a54128fSAndroid Build Coastguard Worker }
1173*6a54128fSAndroid Build Coastguard Worker
1174*6a54128fSAndroid Build Coastguard Worker //
1175*6a54128fSAndroid Build Coastguard Worker // Done
1176*6a54128fSAndroid Build Coastguard Worker //
1177*6a54128fSAndroid Build Coastguard Worker
1178*6a54128fSAndroid Build Coastguard Worker *channel = io;
1179*6a54128fSAndroid Build Coastguard Worker
1180*6a54128fSAndroid Build Coastguard Worker
1181*6a54128fSAndroid Build Coastguard Worker }
1182*6a54128fSAndroid Build Coastguard Worker __finally{
1183*6a54128fSAndroid Build Coastguard Worker
1184*6a54128fSAndroid Build Coastguard Worker if(0 != Errno)
1185*6a54128fSAndroid Build Coastguard Worker {
1186*6a54128fSAndroid Build Coastguard Worker //
1187*6a54128fSAndroid Build Coastguard Worker // Cleanup
1188*6a54128fSAndroid Build Coastguard Worker //
1189*6a54128fSAndroid Build Coastguard Worker
1190*6a54128fSAndroid Build Coastguard Worker if (NULL != io)
1191*6a54128fSAndroid Build Coastguard Worker {
1192*6a54128fSAndroid Build Coastguard Worker free(io->name);
1193*6a54128fSAndroid Build Coastguard Worker free(io);
1194*6a54128fSAndroid Build Coastguard Worker }
1195*6a54128fSAndroid Build Coastguard Worker
1196*6a54128fSAndroid Build Coastguard Worker if (NULL != NtData)
1197*6a54128fSAndroid Build Coastguard Worker {
1198*6a54128fSAndroid Build Coastguard Worker if(NULL != NtData->Handle)
1199*6a54128fSAndroid Build Coastguard Worker {
1200*6a54128fSAndroid Build Coastguard Worker _UnlockDrive(NtData->Handle);
1201*6a54128fSAndroid Build Coastguard Worker _CloseDisk(NtData->Handle);
1202*6a54128fSAndroid Build Coastguard Worker }
1203*6a54128fSAndroid Build Coastguard Worker
1204*6a54128fSAndroid Build Coastguard Worker free(NtData->Buffer);
1205*6a54128fSAndroid Build Coastguard Worker free(NtData);
1206*6a54128fSAndroid Build Coastguard Worker }
1207*6a54128fSAndroid Build Coastguard Worker }
1208*6a54128fSAndroid Build Coastguard Worker }
1209*6a54128fSAndroid Build Coastguard Worker
1210*6a54128fSAndroid Build Coastguard Worker return Errno;
1211*6a54128fSAndroid Build Coastguard Worker }
1212*6a54128fSAndroid Build Coastguard Worker
1213*6a54128fSAndroid Build Coastguard Worker
1214*6a54128fSAndroid Build Coastguard Worker //
1215*6a54128fSAndroid Build Coastguard Worker // Close api
1216*6a54128fSAndroid Build Coastguard Worker //
1217*6a54128fSAndroid Build Coastguard Worker
1218*6a54128fSAndroid Build Coastguard Worker static
1219*6a54128fSAndroid Build Coastguard Worker errcode_t
nt_close(io_channel channel)1220*6a54128fSAndroid Build Coastguard Worker nt_close(io_channel channel)
1221*6a54128fSAndroid Build Coastguard Worker {
1222*6a54128fSAndroid Build Coastguard Worker PNT_PRIVATE_DATA NtData = NULL;
1223*6a54128fSAndroid Build Coastguard Worker
1224*6a54128fSAndroid Build Coastguard Worker if(NULL == channel)
1225*6a54128fSAndroid Build Coastguard Worker {
1226*6a54128fSAndroid Build Coastguard Worker return 0;
1227*6a54128fSAndroid Build Coastguard Worker }
1228*6a54128fSAndroid Build Coastguard Worker
1229*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
1230*6a54128fSAndroid Build Coastguard Worker NtData = (PNT_PRIVATE_DATA) channel->private_data;
1231*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
1232*6a54128fSAndroid Build Coastguard Worker
1233*6a54128fSAndroid Build Coastguard Worker if (--channel->refcount > 0)
1234*6a54128fSAndroid Build Coastguard Worker {
1235*6a54128fSAndroid Build Coastguard Worker return 0;
1236*6a54128fSAndroid Build Coastguard Worker }
1237*6a54128fSAndroid Build Coastguard Worker
1238*6a54128fSAndroid Build Coastguard Worker free(channel->name);
1239*6a54128fSAndroid Build Coastguard Worker free(channel);
1240*6a54128fSAndroid Build Coastguard Worker
1241*6a54128fSAndroid Build Coastguard Worker if (NULL != NtData)
1242*6a54128fSAndroid Build Coastguard Worker {
1243*6a54128fSAndroid Build Coastguard Worker if(NULL != NtData->Handle)
1244*6a54128fSAndroid Build Coastguard Worker {
1245*6a54128fSAndroid Build Coastguard Worker _DismountDrive(NtData->Handle);
1246*6a54128fSAndroid Build Coastguard Worker _UnlockDrive(NtData->Handle);
1247*6a54128fSAndroid Build Coastguard Worker _CloseDisk(NtData->Handle);
1248*6a54128fSAndroid Build Coastguard Worker }
1249*6a54128fSAndroid Build Coastguard Worker
1250*6a54128fSAndroid Build Coastguard Worker free(NtData->Buffer);
1251*6a54128fSAndroid Build Coastguard Worker free(NtData);
1252*6a54128fSAndroid Build Coastguard Worker }
1253*6a54128fSAndroid Build Coastguard Worker
1254*6a54128fSAndroid Build Coastguard Worker return 0;
1255*6a54128fSAndroid Build Coastguard Worker }
1256*6a54128fSAndroid Build Coastguard Worker
1257*6a54128fSAndroid Build Coastguard Worker
1258*6a54128fSAndroid Build Coastguard Worker
1259*6a54128fSAndroid Build Coastguard Worker //
1260*6a54128fSAndroid Build Coastguard Worker // set block size
1261*6a54128fSAndroid Build Coastguard Worker //
1262*6a54128fSAndroid Build Coastguard Worker
1263*6a54128fSAndroid Build Coastguard Worker static
1264*6a54128fSAndroid Build Coastguard Worker errcode_t
nt_set_blksize(io_channel channel,int blksize)1265*6a54128fSAndroid Build Coastguard Worker nt_set_blksize(io_channel channel, int blksize)
1266*6a54128fSAndroid Build Coastguard Worker {
1267*6a54128fSAndroid Build Coastguard Worker PNT_PRIVATE_DATA NtData = NULL;
1268*6a54128fSAndroid Build Coastguard Worker
1269*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
1270*6a54128fSAndroid Build Coastguard Worker NtData = (PNT_PRIVATE_DATA) channel->private_data;
1271*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
1272*6a54128fSAndroid Build Coastguard Worker
1273*6a54128fSAndroid Build Coastguard Worker if (channel->block_size != blksize)
1274*6a54128fSAndroid Build Coastguard Worker {
1275*6a54128fSAndroid Build Coastguard Worker channel->block_size = blksize;
1276*6a54128fSAndroid Build Coastguard Worker
1277*6a54128fSAndroid Build Coastguard Worker free(NtData->Buffer);
1278*6a54128fSAndroid Build Coastguard Worker NtData->BufferBlockNumber = 0xffffffff;
1279*6a54128fSAndroid Build Coastguard Worker NtData->BufferSize = channel->block_size;
1280*6a54128fSAndroid Build Coastguard Worker ASSERT(0 == (NtData->BufferSize % 512));
1281*6a54128fSAndroid Build Coastguard Worker
1282*6a54128fSAndroid Build Coastguard Worker NtData->Buffer = malloc(NtData->BufferSize);
1283*6a54128fSAndroid Build Coastguard Worker
1284*6a54128fSAndroid Build Coastguard Worker if (NULL == NtData->Buffer)
1285*6a54128fSAndroid Build Coastguard Worker {
1286*6a54128fSAndroid Build Coastguard Worker return ENOMEM;
1287*6a54128fSAndroid Build Coastguard Worker }
1288*6a54128fSAndroid Build Coastguard Worker
1289*6a54128fSAndroid Build Coastguard Worker }
1290*6a54128fSAndroid Build Coastguard Worker
1291*6a54128fSAndroid Build Coastguard Worker return 0;
1292*6a54128fSAndroid Build Coastguard Worker }
1293*6a54128fSAndroid Build Coastguard Worker
1294*6a54128fSAndroid Build Coastguard Worker
1295*6a54128fSAndroid Build Coastguard Worker //
1296*6a54128fSAndroid Build Coastguard Worker // read block
1297*6a54128fSAndroid Build Coastguard Worker //
1298*6a54128fSAndroid Build Coastguard Worker
1299*6a54128fSAndroid Build Coastguard Worker static
1300*6a54128fSAndroid Build Coastguard Worker errcode_t
nt_read_blk(io_channel channel,unsigned long block,int count,void * buf)1301*6a54128fSAndroid Build Coastguard Worker nt_read_blk(io_channel channel, unsigned long block,
1302*6a54128fSAndroid Build Coastguard Worker int count, void *buf)
1303*6a54128fSAndroid Build Coastguard Worker {
1304*6a54128fSAndroid Build Coastguard Worker PVOID BufferToRead;
1305*6a54128fSAndroid Build Coastguard Worker ULONG SizeToRead;
1306*6a54128fSAndroid Build Coastguard Worker ULONG Size;
1307*6a54128fSAndroid Build Coastguard Worker LARGE_INTEGER Offset;
1308*6a54128fSAndroid Build Coastguard Worker PNT_PRIVATE_DATA NtData = NULL;
1309*6a54128fSAndroid Build Coastguard Worker unsigned Errno = 0;
1310*6a54128fSAndroid Build Coastguard Worker
1311*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
1312*6a54128fSAndroid Build Coastguard Worker NtData = (PNT_PRIVATE_DATA) channel->private_data;
1313*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
1314*6a54128fSAndroid Build Coastguard Worker
1315*6a54128fSAndroid Build Coastguard Worker //
1316*6a54128fSAndroid Build Coastguard Worker // If it's in the cache, use it!
1317*6a54128fSAndroid Build Coastguard Worker //
1318*6a54128fSAndroid Build Coastguard Worker
1319*6a54128fSAndroid Build Coastguard Worker if ((1 == count) &&
1320*6a54128fSAndroid Build Coastguard Worker (block == NtData->BufferBlockNumber) &&
1321*6a54128fSAndroid Build Coastguard Worker (NtData->BufferBlockNumber != 0xffffffff))
1322*6a54128fSAndroid Build Coastguard Worker {
1323*6a54128fSAndroid Build Coastguard Worker memcpy(buf, NtData->Buffer, channel->block_size);
1324*6a54128fSAndroid Build Coastguard Worker return 0;
1325*6a54128fSAndroid Build Coastguard Worker }
1326*6a54128fSAndroid Build Coastguard Worker
1327*6a54128fSAndroid Build Coastguard Worker Size = (count < 0) ? (ULONG)(-count) : (ULONG)(count * channel->block_size);
1328*6a54128fSAndroid Build Coastguard Worker
1329*6a54128fSAndroid Build Coastguard Worker Offset.QuadPart = block * channel->block_size;
1330*6a54128fSAndroid Build Coastguard Worker
1331*6a54128fSAndroid Build Coastguard Worker //
1332*6a54128fSAndroid Build Coastguard Worker // If not fit to the block
1333*6a54128fSAndroid Build Coastguard Worker //
1334*6a54128fSAndroid Build Coastguard Worker
1335*6a54128fSAndroid Build Coastguard Worker if(Size <= NtData->BufferSize)
1336*6a54128fSAndroid Build Coastguard Worker {
1337*6a54128fSAndroid Build Coastguard Worker //
1338*6a54128fSAndroid Build Coastguard Worker // Update the cache
1339*6a54128fSAndroid Build Coastguard Worker //
1340*6a54128fSAndroid Build Coastguard Worker
1341*6a54128fSAndroid Build Coastguard Worker NtData->BufferBlockNumber = block;
1342*6a54128fSAndroid Build Coastguard Worker BufferToRead = NtData->Buffer;
1343*6a54128fSAndroid Build Coastguard Worker SizeToRead = NtData->BufferSize;
1344*6a54128fSAndroid Build Coastguard Worker }
1345*6a54128fSAndroid Build Coastguard Worker else
1346*6a54128fSAndroid Build Coastguard Worker {
1347*6a54128fSAndroid Build Coastguard Worker SizeToRead = Size;
1348*6a54128fSAndroid Build Coastguard Worker BufferToRead = buf;
1349*6a54128fSAndroid Build Coastguard Worker ASSERT(0 == (SizeToRead % channel->block_size));
1350*6a54128fSAndroid Build Coastguard Worker }
1351*6a54128fSAndroid Build Coastguard Worker
1352*6a54128fSAndroid Build Coastguard Worker if(!_RawRead(NtData->Handle, Offset, SizeToRead, BufferToRead, &Errno))
1353*6a54128fSAndroid Build Coastguard Worker {
1354*6a54128fSAndroid Build Coastguard Worker
1355*6a54128fSAndroid Build Coastguard Worker if (channel->read_error)
1356*6a54128fSAndroid Build Coastguard Worker {
1357*6a54128fSAndroid Build Coastguard Worker return (channel->read_error)(channel, block, count, buf,
1358*6a54128fSAndroid Build Coastguard Worker Size, 0, Errno);
1359*6a54128fSAndroid Build Coastguard Worker }
1360*6a54128fSAndroid Build Coastguard Worker else
1361*6a54128fSAndroid Build Coastguard Worker {
1362*6a54128fSAndroid Build Coastguard Worker return Errno;
1363*6a54128fSAndroid Build Coastguard Worker }
1364*6a54128fSAndroid Build Coastguard Worker }
1365*6a54128fSAndroid Build Coastguard Worker
1366*6a54128fSAndroid Build Coastguard Worker
1367*6a54128fSAndroid Build Coastguard Worker if(BufferToRead != buf)
1368*6a54128fSAndroid Build Coastguard Worker {
1369*6a54128fSAndroid Build Coastguard Worker ASSERT(Size <= SizeToRead);
1370*6a54128fSAndroid Build Coastguard Worker memcpy(buf, BufferToRead, Size);
1371*6a54128fSAndroid Build Coastguard Worker }
1372*6a54128fSAndroid Build Coastguard Worker
1373*6a54128fSAndroid Build Coastguard Worker return 0;
1374*6a54128fSAndroid Build Coastguard Worker }
1375*6a54128fSAndroid Build Coastguard Worker
1376*6a54128fSAndroid Build Coastguard Worker
1377*6a54128fSAndroid Build Coastguard Worker //
1378*6a54128fSAndroid Build Coastguard Worker // write block
1379*6a54128fSAndroid Build Coastguard Worker //
1380*6a54128fSAndroid Build Coastguard Worker
1381*6a54128fSAndroid Build Coastguard Worker static
1382*6a54128fSAndroid Build Coastguard Worker errcode_t
nt_write_blk(io_channel channel,unsigned long block,int count,const void * buf)1383*6a54128fSAndroid Build Coastguard Worker nt_write_blk(io_channel channel, unsigned long block,
1384*6a54128fSAndroid Build Coastguard Worker int count, const void *buf)
1385*6a54128fSAndroid Build Coastguard Worker {
1386*6a54128fSAndroid Build Coastguard Worker ULONG SizeToWrite;
1387*6a54128fSAndroid Build Coastguard Worker LARGE_INTEGER Offset;
1388*6a54128fSAndroid Build Coastguard Worker PNT_PRIVATE_DATA NtData = NULL;
1389*6a54128fSAndroid Build Coastguard Worker unsigned Errno = 0;
1390*6a54128fSAndroid Build Coastguard Worker
1391*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
1392*6a54128fSAndroid Build Coastguard Worker NtData = (PNT_PRIVATE_DATA) channel->private_data;
1393*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
1394*6a54128fSAndroid Build Coastguard Worker
1395*6a54128fSAndroid Build Coastguard Worker if(NtData->OpenedReadonly)
1396*6a54128fSAndroid Build Coastguard Worker {
1397*6a54128fSAndroid Build Coastguard Worker return EACCES;
1398*6a54128fSAndroid Build Coastguard Worker }
1399*6a54128fSAndroid Build Coastguard Worker
1400*6a54128fSAndroid Build Coastguard Worker if (count == 1)
1401*6a54128fSAndroid Build Coastguard Worker {
1402*6a54128fSAndroid Build Coastguard Worker SizeToWrite = channel->block_size;
1403*6a54128fSAndroid Build Coastguard Worker }
1404*6a54128fSAndroid Build Coastguard Worker else
1405*6a54128fSAndroid Build Coastguard Worker {
1406*6a54128fSAndroid Build Coastguard Worker NtData->BufferBlockNumber = 0xffffffff;
1407*6a54128fSAndroid Build Coastguard Worker
1408*6a54128fSAndroid Build Coastguard Worker if (count < 0)
1409*6a54128fSAndroid Build Coastguard Worker {
1410*6a54128fSAndroid Build Coastguard Worker SizeToWrite = (ULONG)(-count);
1411*6a54128fSAndroid Build Coastguard Worker }
1412*6a54128fSAndroid Build Coastguard Worker else
1413*6a54128fSAndroid Build Coastguard Worker {
1414*6a54128fSAndroid Build Coastguard Worker SizeToWrite = (ULONG)(count * channel->block_size);
1415*6a54128fSAndroid Build Coastguard Worker }
1416*6a54128fSAndroid Build Coastguard Worker }
1417*6a54128fSAndroid Build Coastguard Worker
1418*6a54128fSAndroid Build Coastguard Worker
1419*6a54128fSAndroid Build Coastguard Worker ASSERT(0 == (SizeToWrite % 512));
1420*6a54128fSAndroid Build Coastguard Worker Offset.QuadPart = block * channel->block_size;
1421*6a54128fSAndroid Build Coastguard Worker
1422*6a54128fSAndroid Build Coastguard Worker if(!_RawWrite(NtData->Handle, Offset, SizeToWrite, buf, &Errno))
1423*6a54128fSAndroid Build Coastguard Worker {
1424*6a54128fSAndroid Build Coastguard Worker if (channel->write_error)
1425*6a54128fSAndroid Build Coastguard Worker {
1426*6a54128fSAndroid Build Coastguard Worker return (channel->write_error)(channel, block, count, buf,
1427*6a54128fSAndroid Build Coastguard Worker SizeToWrite, 0, Errno);
1428*6a54128fSAndroid Build Coastguard Worker }
1429*6a54128fSAndroid Build Coastguard Worker else
1430*6a54128fSAndroid Build Coastguard Worker {
1431*6a54128fSAndroid Build Coastguard Worker return Errno;
1432*6a54128fSAndroid Build Coastguard Worker }
1433*6a54128fSAndroid Build Coastguard Worker }
1434*6a54128fSAndroid Build Coastguard Worker
1435*6a54128fSAndroid Build Coastguard Worker
1436*6a54128fSAndroid Build Coastguard Worker //
1437*6a54128fSAndroid Build Coastguard Worker // Stash a copy.
1438*6a54128fSAndroid Build Coastguard Worker //
1439*6a54128fSAndroid Build Coastguard Worker
1440*6a54128fSAndroid Build Coastguard Worker if(SizeToWrite >= NtData->BufferSize)
1441*6a54128fSAndroid Build Coastguard Worker {
1442*6a54128fSAndroid Build Coastguard Worker NtData->BufferBlockNumber = block;
1443*6a54128fSAndroid Build Coastguard Worker memcpy(NtData->Buffer, buf, NtData->BufferSize);
1444*6a54128fSAndroid Build Coastguard Worker }
1445*6a54128fSAndroid Build Coastguard Worker
1446*6a54128fSAndroid Build Coastguard Worker NtData->Written = TRUE;
1447*6a54128fSAndroid Build Coastguard Worker
1448*6a54128fSAndroid Build Coastguard Worker return 0;
1449*6a54128fSAndroid Build Coastguard Worker
1450*6a54128fSAndroid Build Coastguard Worker }
1451*6a54128fSAndroid Build Coastguard Worker
1452*6a54128fSAndroid Build Coastguard Worker
1453*6a54128fSAndroid Build Coastguard Worker
1454*6a54128fSAndroid Build Coastguard Worker //
1455*6a54128fSAndroid Build Coastguard Worker // Flush data buffers to disk. Since we are currently using a
1456*6a54128fSAndroid Build Coastguard Worker // write-through cache, this is a no-op.
1457*6a54128fSAndroid Build Coastguard Worker //
1458*6a54128fSAndroid Build Coastguard Worker
1459*6a54128fSAndroid Build Coastguard Worker static
1460*6a54128fSAndroid Build Coastguard Worker errcode_t
nt_flush(io_channel channel)1461*6a54128fSAndroid Build Coastguard Worker nt_flush(io_channel channel)
1462*6a54128fSAndroid Build Coastguard Worker {
1463*6a54128fSAndroid Build Coastguard Worker PNT_PRIVATE_DATA NtData = NULL;
1464*6a54128fSAndroid Build Coastguard Worker
1465*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
1466*6a54128fSAndroid Build Coastguard Worker NtData = (PNT_PRIVATE_DATA) channel->private_data;
1467*6a54128fSAndroid Build Coastguard Worker EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
1468*6a54128fSAndroid Build Coastguard Worker
1469*6a54128fSAndroid Build Coastguard Worker if(NtData->OpenedReadonly)
1470*6a54128fSAndroid Build Coastguard Worker {
1471*6a54128fSAndroid Build Coastguard Worker return 0; // EACCESS;
1472*6a54128fSAndroid Build Coastguard Worker }
1473*6a54128fSAndroid Build Coastguard Worker
1474*6a54128fSAndroid Build Coastguard Worker
1475*6a54128fSAndroid Build Coastguard Worker //
1476*6a54128fSAndroid Build Coastguard Worker // Flush file buffers.
1477*6a54128fSAndroid Build Coastguard Worker //
1478*6a54128fSAndroid Build Coastguard Worker
1479*6a54128fSAndroid Build Coastguard Worker _FlushDrive(NtData->Handle);
1480*6a54128fSAndroid Build Coastguard Worker
1481*6a54128fSAndroid Build Coastguard Worker
1482*6a54128fSAndroid Build Coastguard Worker //
1483*6a54128fSAndroid Build Coastguard Worker // Test and correct partition type.
1484*6a54128fSAndroid Build Coastguard Worker //
1485*6a54128fSAndroid Build Coastguard Worker
1486*6a54128fSAndroid Build Coastguard Worker if(NtData->Written)
1487*6a54128fSAndroid Build Coastguard Worker {
1488*6a54128fSAndroid Build Coastguard Worker _SetPartType(NtData->Handle, 0x83);
1489*6a54128fSAndroid Build Coastguard Worker }
1490*6a54128fSAndroid Build Coastguard Worker
1491*6a54128fSAndroid Build Coastguard Worker return 0;
1492*6a54128fSAndroid Build Coastguard Worker }
1493*6a54128fSAndroid Build Coastguard Worker
1494*6a54128fSAndroid Build Coastguard Worker
1495