Extra debug info
[lwext4.git] / blockdev / filedev_win / 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 \r
41 /**@brief   Default filename.*/\r
42 static const char *fname = "ext2";\r
43 \r
44 /**@brief   IO block size.*/\r
45 #define EXT4_IORAW_BSIZE      512\r
46 \r
47 /**@brief   Image file descriptor.*/\r
48 static HANDLE dev_file;\r
49 \r
50 \r
51 /**********************BLOCKDEV INTERFACE**************************************/\r
52 static int io_raw_open(struct ext4_blockdev *bdev);\r
53 static int io_raw_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,\r
54     uint32_t blk_cnt);\r
55 static int io_raw_bwrite(struct ext4_blockdev *bdev, const void *buf,\r
56     uint64_t blk_id, uint32_t blk_cnt);\r
57 static int io_raw_close(struct  ext4_blockdev *bdev);\r
58 \r
59 \r
60 \r
61 \r
62 /******************************************************************************/\r
63 EXT4_BLOCKDEV_STATIC_INSTANCE(\r
64     _filedev,\r
65     EXT4_IORAW_BSIZE,\r
66     0,\r
67     io_raw_open,\r
68     io_raw_bread,\r
69     io_raw_bwrite,\r
70     io_raw_close\r
71 );\r
72 \r
73 /******************************************************************************/\r
74 static int io_raw_open(struct ext4_blockdev *bdev)\r
75 {\r
76     char path[64];\r
77     DISK_GEOMETRY   pdg;\r
78     uint64_t disk_size;\r
79     BOOL bResult   = FALSE;\r
80     DWORD junk;\r
81 \r
82     sprintf(path, "\\\\.\\%s", fname);\r
83 \r
84     dev_file = CreateFile (path,\r
85             GENERIC_READ | GENERIC_WRITE,\r
86             FILE_SHARE_WRITE | FILE_SHARE_READ,\r
87             NULL,\r
88             OPEN_EXISTING,\r
89             FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,\r
90             NULL);\r
91 \r
92     if (dev_file == INVALID_HANDLE_VALUE){\r
93         return EIO;\r
94     }\r
95 \r
96     bResult = DeviceIoControl(dev_file,\r
97             IOCTL_DISK_GET_DRIVE_GEOMETRY,\r
98             NULL, 0,\r
99             &pdg, sizeof(pdg),\r
100             &junk,\r
101             (LPOVERLAPPED) NULL);\r
102 \r
103     if(bResult == FALSE){\r
104         CloseHandle(dev_file);\r
105         return EIO;\r
106     }\r
107 \r
108 \r
109     disk_size = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *\r
110             (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;\r
111 \r
112     _filedev.ph_bsize = pdg.BytesPerSector;\r
113     _filedev.ph_bcnt  = disk_size / pdg.BytesPerSector;\r
114 \r
115 \r
116     return EOK;\r
117 }\r
118 \r
119 /******************************************************************************/\r
120 \r
121 static int io_raw_bread(struct  ext4_blockdev *bdev, void *buf, uint64_t blk_id,\r
122     uint32_t blk_cnt)\r
123 {\r
124     long hipart = blk_id >> (32-9);\r
125     long lopart = blk_id << 9;\r
126     long err;\r
127 \r
128     SetLastError (0);\r
129     lopart = SetFilePointer (dev_file, lopart, &hipart, FILE_BEGIN);\r
130 \r
131     if (lopart == -1  &&  NO_ERROR != (err = GetLastError ()))\r
132     {\r
133         return EIO;\r
134     }\r
135 \r
136     DWORD   n;\r
137 \r
138     if (!ReadFile (dev_file, buf, blk_cnt * 512, &n, NULL))\r
139     {\r
140         err = GetLastError ();\r
141         return EIO;\r
142     }\r
143     return EOK;\r
144 }\r
145 \r
146 /******************************************************************************/\r
147 static int io_raw_bwrite(struct ext4_blockdev *bdev, const void *buf,\r
148     uint64_t blk_id, uint32_t blk_cnt)\r
149 {\r
150     long hipart = blk_id >> (32-9);\r
151     long lopart = blk_id << 9;\r
152     long err;\r
153 \r
154     SetLastError (0);\r
155     lopart = SetFilePointer (dev_file, lopart, &hipart, FILE_BEGIN);\r
156 \r
157     if (lopart == -1  &&  NO_ERROR != (err = GetLastError ()))\r
158     {\r
159         return EIO;\r
160     }\r
161 \r
162     DWORD   n;\r
163 \r
164     if (!WriteFile (dev_file, buf, blk_cnt * 512, &n, NULL))\r
165     {\r
166         err = GetLastError ();\r
167         return EIO;\r
168     }\r
169     return EOK;\r
170 }\r
171 \r
172 /******************************************************************************/\r
173 static int io_raw_close(struct  ext4_blockdev *bdev)\r
174 {\r
175     CloseHandle(dev_file);\r
176     return EOK;\r
177 }\r
178 \r
179 /******************************************************************************/\r
180 struct  ext4_blockdev* ext4_io_raw_dev_get(void)\r
181 {\r
182     return &_filedev;\r
183 }\r
184 /******************************************************************************/\r
185 void ext4_io_raw_filename(const char *n)\r
186 {\r
187     fname = n;\r
188 }\r
189 \r
190 /******************************************************************************/\r
191 #endif\r
192 \r