|
11 | 11 | #include "compiler-attributes.h" |
12 | 12 |
|
13 | 13 |
|
14 | | -static int __nvme_transport_handle_open_direct(struct libnvme_transport_handle *hdl, const char *name) |
| 14 | +/* fstat implementation for device HANDLE */ |
| 15 | +static int __libnvme_fd_fstat(libnvme_fd_t fd, struct stat *buf) |
| 16 | +{ |
| 17 | + BY_HANDLE_FILE_INFORMATION file_info; |
| 18 | + ULARGE_INTEGER ull; |
| 19 | + DWORD file_type; |
| 20 | + |
| 21 | + if (!buf) { |
| 22 | + errno = EINVAL; |
| 23 | + return -1; |
| 24 | + } |
| 25 | + |
| 26 | + /* Check for invalid handle */ |
| 27 | + if (fd == INVALID_HANDLE_VALUE || fd == NULL) { |
| 28 | + errno = EBADF; |
| 29 | + return -1; |
| 30 | + } |
| 31 | + |
| 32 | + /* |
| 33 | + * GetFileInformationByHandle() does not work for all device HANDLEs |
| 34 | + * (e.g. raw \\\\.\\PhysicalDriveN). For those, fall back to file type. |
| 35 | + */ |
| 36 | + if (!GetFileInformationByHandle(fd, &file_info)) { |
| 37 | + file_type = GetFileType(fd); |
| 38 | + if (file_type == FILE_TYPE_DISK || file_type == FILE_TYPE_CHAR) { |
| 39 | + memset(buf, 0, sizeof(*buf)); |
| 40 | + buf->st_mode = S_IFBLK | 0600; |
| 41 | + buf->st_nlink = 1; |
| 42 | + return 0; |
| 43 | + } |
| 44 | + |
| 45 | + errno = EBADF; |
| 46 | + return -1; |
| 47 | + } |
| 48 | + |
| 49 | + /* Fill in the stat structure */ |
| 50 | + memset(buf, 0, sizeof(*buf)); |
| 51 | + |
| 52 | + /* Convert Windows file attributes to stat mode */ |
| 53 | + if (file_info.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) |
| 54 | + /* Windows device files should be marked as block devices */ |
| 55 | + /* This is used by libnvme_verify_chr to check device type */ |
| 56 | + buf->st_mode = S_IFBLK | 0600; |
| 57 | + else if (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
| 58 | + buf->st_mode = S_IFDIR | 0755; |
| 59 | + else |
| 60 | + buf->st_mode = S_IFREG | 0644; |
| 61 | + |
| 62 | + /* File size */ |
| 63 | + buf->st_size = (((off_t)file_info.nFileSizeHigh << 32) |
| 64 | + | file_info.nFileSizeLow); |
| 65 | + |
| 66 | + /* Number of hard links */ |
| 67 | + buf->st_nlink = file_info.nNumberOfLinks; |
| 68 | + |
| 69 | + /* Convert FILETIME to time_t for timestamps */ |
| 70 | + /* Windows FILETIME is 100-nanosecond intervals since Jan 1, 1601 */ |
| 71 | + /* Unix time_t is seconds since Jan 1, 1970 */ |
| 72 | + ull.LowPart = file_info.ftLastWriteTime.dwLowDateTime; |
| 73 | + ull.HighPart = file_info.ftLastWriteTime.dwHighDateTime; |
| 74 | + buf->st_mtime = (time_t)((ull.QuadPart / 10000000ULL) - 11644473600ULL); |
| 75 | + |
| 76 | + ull.LowPart = file_info.ftLastAccessTime.dwLowDateTime; |
| 77 | + ull.HighPart = file_info.ftLastAccessTime.dwHighDateTime; |
| 78 | + buf->st_atime = (time_t)((ull.QuadPart / 10000000ULL) - 11644473600ULL); |
| 79 | + |
| 80 | + ull.LowPart = file_info.ftCreationTime.dwLowDateTime; |
| 81 | + ull.HighPart = file_info.ftCreationTime.dwHighDateTime; |
| 82 | + buf->st_ctime = (time_t)((ull.QuadPart / 10000000ULL) - 11644473600ULL); |
| 83 | + |
| 84 | + return 0; |
| 85 | +} |
| 86 | + |
| 87 | +static int __libnvme_transport_handle_open_direct(struct libnvme_transport_handle *hdl, const char *name) |
15 | 88 | { |
16 | 89 | char device_path[MAX_PATH]; |
17 | 90 | HANDLE h; |
@@ -53,7 +126,7 @@ static int __nvme_transport_handle_open_direct(struct libnvme_transport_handle * |
53 | 126 |
|
54 | 127 | hdl->fd = h; |
55 | 128 |
|
56 | | - libnvme_fstat(hdl->fd, &hdl->stat); |
| 129 | + __libnvme_fd_fstat(hdl->fd, &hdl->stat); |
57 | 130 |
|
58 | 131 | /* Windows doesn't distinguish 32/64-bit ioctl, assume 64-bit capable */ |
59 | 132 | hdl->ioctl_admin64 = true; |
@@ -96,7 +169,7 @@ __public int libnvme_open(struct libnvme_global_ctx *ctx, const char *name, |
96 | 169 | libnvme_close(hdl); |
97 | 170 | return -ENOTSUP; |
98 | 171 | } else { |
99 | | - ret = __nvme_transport_handle_open_direct(hdl, name); |
| 172 | + ret = __libnvme_transport_handle_open_direct(hdl, name); |
100 | 173 | } |
101 | 174 |
|
102 | 175 | if (ret) { |
@@ -132,76 +205,3 @@ __public void libnvme_close(struct libnvme_transport_handle *hdl) |
132 | 205 | break; |
133 | 206 | } |
134 | 207 | } |
135 | | - |
136 | | -/* Platform-specific fstat wrapper for libnvme_fd_t */ |
137 | | -__public int libnvme_fstat(libnvme_fd_t fd, struct stat *buf) |
138 | | -{ |
139 | | - BY_HANDLE_FILE_INFORMATION file_info; |
140 | | - ULARGE_INTEGER ull; |
141 | | - DWORD file_type; |
142 | | - |
143 | | - if (!buf) { |
144 | | - errno = EINVAL; |
145 | | - return -1; |
146 | | - } |
147 | | - |
148 | | - /* Check for invalid handle */ |
149 | | - if (fd == INVALID_HANDLE_VALUE || fd == NULL) { |
150 | | - errno = EBADF; |
151 | | - return -1; |
152 | | - } |
153 | | - |
154 | | - /* |
155 | | - * GetFileInformationByHandle() does not work for all device HANDLEs |
156 | | - * (e.g. raw \\\\.\\PhysicalDriveN). For those, fall back to file type. |
157 | | - */ |
158 | | - if (!GetFileInformationByHandle(fd, &file_info)) { |
159 | | - file_type = GetFileType(fd); |
160 | | - if (file_type == FILE_TYPE_DISK || file_type == FILE_TYPE_CHAR) { |
161 | | - memset(buf, 0, sizeof(*buf)); |
162 | | - buf->st_mode = S_IFBLK | 0600; |
163 | | - buf->st_nlink = 1; |
164 | | - return 0; |
165 | | - } |
166 | | - |
167 | | - errno = EBADF; |
168 | | - return -1; |
169 | | - } |
170 | | - |
171 | | - /* Fill in the stat structure */ |
172 | | - memset(buf, 0, sizeof(*buf)); |
173 | | - |
174 | | - /* Convert Windows file attributes to stat mode */ |
175 | | - if (file_info.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) |
176 | | - /* Windows device files should be marked as block devices */ |
177 | | - /* This is used by libnvme_verify_chr to check device type */ |
178 | | - buf->st_mode = S_IFBLK | 0600; |
179 | | - else if (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
180 | | - buf->st_mode = S_IFDIR | 0755; |
181 | | - else |
182 | | - buf->st_mode = S_IFREG | 0644; |
183 | | - |
184 | | - /* File size */ |
185 | | - buf->st_size = (((off_t)file_info.nFileSizeHigh << 32) |
186 | | - | file_info.nFileSizeLow); |
187 | | - |
188 | | - /* Number of hard links */ |
189 | | - buf->st_nlink = file_info.nNumberOfLinks; |
190 | | - |
191 | | - /* Convert FILETIME to time_t for timestamps */ |
192 | | - /* Windows FILETIME is 100-nanosecond intervals since Jan 1, 1601 */ |
193 | | - /* Unix time_t is seconds since Jan 1, 1970 */ |
194 | | - ull.LowPart = file_info.ftLastWriteTime.dwLowDateTime; |
195 | | - ull.HighPart = file_info.ftLastWriteTime.dwHighDateTime; |
196 | | - buf->st_mtime = (time_t)((ull.QuadPart / 10000000ULL) - 11644473600ULL); |
197 | | - |
198 | | - ull.LowPart = file_info.ftLastAccessTime.dwLowDateTime; |
199 | | - ull.HighPart = file_info.ftLastAccessTime.dwHighDateTime; |
200 | | - buf->st_atime = (time_t)((ull.QuadPart / 10000000ULL) - 11644473600ULL); |
201 | | - |
202 | | - ull.LowPart = file_info.ftCreationTime.dwLowDateTime; |
203 | | - ull.HighPart = file_info.ftCreationTime.dwHighDateTime; |
204 | | - buf->st_ctime = (time_t)((ull.QuadPart / 10000000ULL) - 11644473600ULL); |
205 | | - |
206 | | - return 0; |
207 | | -} |
0 commit comments