xref: /aosp_15_r20/external/e2fsprogs/lib/ext2fs/nt_io.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
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