Demo apps refactoring
[lwext4.git] / blockdev / windows / io_raw.c
1 /*\r
2  * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  *\r
9  * - Redistributions of source code must retain the above copyright\r
10  *   notice, this list of conditions and the following disclaimer.\r
11  * - Redistributions in binary form must reproduce the above copyright\r
12  *   notice, this list of conditions and the following disclaimer in the\r
13  *   documentation and/or other materials provided with the distribution.\r
14  * - The name of the author may not be used to endorse or promote products\r
15  *   derived from this software without specific prior written permission.\r
16  *\r
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  */\r
28 \r
29 #include <ext4_config.h>\r
30 #include <ext4_blockdev.h>\r
31 #include <ext4_errno.h>\r
32 #include <stdio.h>\r
33 #include <stdbool.h>\r
34 #include <string.h>\r
35 \r
36 #ifdef WIN32\r
37 #include <windows.h>\r
38 #include <winioctl.h>\r
39 \r
40 /**@brief   Default filename.*/\r
41 static const char *fname = "ext2";\r
42 \r
43 /**@brief   IO block size.*/\r
44 #define EXT4_IORAW_BSIZE 512\r
45 \r
46 /**@brief   Image file descriptor.*/\r
47 static HANDLE dev_file;\r
48 \r
49 /**********************BLOCKDEV INTERFACE**************************************/\r
50 static int io_raw_open(struct ext4_blockdev *bdev);\r
51 static int io_raw_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,\r
52                         uint32_t blk_cnt);\r
53 static int io_raw_bwrite(struct ext4_blockdev *bdev, const void *buf,\r
54                          uint64_t blk_id, uint32_t blk_cnt);\r
55 static int io_raw_close(struct ext4_blockdev *bdev);\r
56 \r
57 /******************************************************************************/\r
58 EXT4_BLOCKDEV_STATIC_INSTANCE(_filedev, EXT4_IORAW_BSIZE, 0, io_raw_open,\r
59                               io_raw_bread, io_raw_bwrite, io_raw_close);\r
60 \r
61 /******************************************************************************/\r
62 static int io_raw_open(struct ext4_blockdev *bdev)\r
63 {\r
64         char path[64];\r
65         DISK_GEOMETRY pdg;\r
66         uint64_t disk_size;\r
67         BOOL bResult = FALSE;\r
68         DWORD junk;\r
69 \r
70         sprintf(path, "\\\\.\\%s", fname);\r
71 \r
72         dev_file =\r
73             CreateFile(path, GENERIC_READ | GENERIC_WRITE,\r
74                        FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
75                        FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);\r
76 \r
77         if (dev_file == INVALID_HANDLE_VALUE) {\r
78                 return EIO;\r
79         }\r
80 \r
81         bResult =\r
82             DeviceIoControl(dev_file, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,\r
83                             &pdg, sizeof(pdg), &junk, (LPOVERLAPPED)NULL);\r
84 \r
85         if (bResult == FALSE) {\r
86                 CloseHandle(dev_file);\r
87                 return EIO;\r
88         }\r
89 \r
90         disk_size = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *\r
91                     (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;\r
92 \r
93         _filedev.ph_bsize = pdg.BytesPerSector;\r
94         _filedev.ph_bcnt = disk_size / pdg.BytesPerSector;\r
95 \r
96         return EOK;\r
97 }\r
98 \r
99 /******************************************************************************/\r
100 \r
101 static int io_raw_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,\r
102                         uint32_t blk_cnt)\r
103 {\r
104         long hipart = blk_id >> (32 - 9);\r
105         long lopart = blk_id << 9;\r
106         long err;\r
107 \r
108         SetLastError(0);\r
109         lopart = SetFilePointer(dev_file, lopart, &hipart, FILE_BEGIN);\r
110 \r
111         if (lopart == -1 && NO_ERROR != (err = GetLastError())) {\r
112                 return EIO;\r
113         }\r
114 \r
115         DWORD n;\r
116 \r
117         if (!ReadFile(dev_file, buf, blk_cnt * 512, &n, NULL)) {\r
118                 err = GetLastError();\r
119                 return EIO;\r
120         }\r
121         return EOK;\r
122 }\r
123 \r
124 /******************************************************************************/\r
125 static int io_raw_bwrite(struct ext4_blockdev *bdev, const void *buf,\r
126                          uint64_t blk_id, uint32_t blk_cnt)\r
127 {\r
128         long hipart = blk_id >> (32 - 9);\r
129         long lopart = blk_id << 9;\r
130         long err;\r
131 \r
132         SetLastError(0);\r
133         lopart = SetFilePointer(dev_file, lopart, &hipart, FILE_BEGIN);\r
134 \r
135         if (lopart == -1 && NO_ERROR != (err = GetLastError())) {\r
136                 return EIO;\r
137         }\r
138 \r
139         DWORD n;\r
140 \r
141         if (!WriteFile(dev_file, buf, blk_cnt * 512, &n, NULL)) {\r
142                 err = GetLastError();\r
143                 return EIO;\r
144         }\r
145         return EOK;\r
146 }\r
147 \r
148 /******************************************************************************/\r
149 static int io_raw_close(struct ext4_blockdev *bdev)\r
150 {\r
151         CloseHandle(dev_file);\r
152         return EOK;\r
153 }\r
154 \r
155 /******************************************************************************/\r
156 struct ext4_blockdev *ext4_io_raw_dev_get(void) { return &_filedev; }\r
157 /******************************************************************************/\r
158 void ext4_io_raw_filename(const char *n) { fname = n; }\r
159 \r
160 /******************************************************************************/\r
161 #endif\r