1 /*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 /* */
19 #if defined(WIN64) || defined(WIN32)
20 #include <windows.h>
21 #endif
22 #include "io3f.h"
23 #include <string.h>
24 #include "async.h"
25 #include "mpalloc.h"
26
27 char *
__fstr2cstr(char * from,int from_len)28 __fstr2cstr(char *from, int from_len)
29 {
30 char *str;
31 int len;
32
33 for (len = from_len; len > 0; len--)
34 if (from[len - 1] != ' ')
35 break;
36 str = _mp_malloc(len + 1);
37 memcpy(str, from, len);
38 str[len] = '\0';
39 return str;
40 }
41
42 void
__cstr_free(char * from)43 __cstr_free(char *from)
44 {
45 _mp_free(from);
46 }
47
48 void
__fcp_cstr(char * to,int to_len,char * from)49 __fcp_cstr(char *to, int to_len, char *from)
50 {
51 char ch;
52
53 if (from)
54 while ((ch = *from++)) {
55 if (to_len-- <= 0)
56 break;
57 *to++ = ch;
58 }
59 while (to_len-- > 0)
60 *to++ = ' ';
61 }
62
63 /* --------------------------------------------------------------- */
64 /* io-related routines needed to support 3f routines */
65 /* --------------------------------------------------------------- */
66
67 /* --------------------------------------------------------------- */
68
69 extern bool __isatty3f(unit) int unit;
70 {
71 void *p;
72 int fd;
73
74 p = __fio_find_unit(unit);
75 if (p == NULL || FIO_FCB_STDUNIT(p)) {
76 switch (unit) {
77 case 0:
78 fd = 2; /* stderr */
79 break;
80 case 5:
81 fd = 0; /* stdin */
82 break;
83 case 6:
84 fd = 1; /* stdout */
85 break;
86 default:
87 return FALSE;
88 }
89 return __io_isatty(fd);
90 }
91 return FALSE;
92 }
93
94 /* --------------------------------------------------------------- */
95
96 extern FILE *__getfile3f(unit) int unit;
97 {
98 void *p;
99
100 p = __fio_find_unit(unit);
101 if (p != NULL) {
102 if (FIO_FCB_ASY_RW(p)) {/* disable any async i/o */
103 FIO_FCB_SET_ASY_RW(p, 0);
104 if (Fio_asy_disable(FIO_FCB_ASYPTR(p)) == -1) {
105 __abort(1, "3F routine found asynchronous I/O error");
106 }
107 }
108 return FIO_FCB_FP(p);
109 }
110 switch (unit) {
111 case 0:
112 return __io_stderr();
113 case 5:
114 return __io_stdin();
115 case 6:
116 return __io_stdout();
117 default:
118 return NULL;
119 }
120 }
121
122 #if defined(WIN64) || defined(WIN32)
123 void
__GetTimeToSecondsSince1970(ULARGE_INTEGER * fileTime,unsigned int * out)124 __GetTimeToSecondsSince1970(ULARGE_INTEGER *fileTime, unsigned int *out)
125 {
126
127 /* From RtlTimeToSecondsSince1970 Function */
128
129 FILETIME *firstFileTime;
130 ULARGE_INTEGER *firstLarge;
131 SYSTEMTIME *firstTime;
132 firstLarge = (ULARGE_INTEGER *)_mp_malloc(sizeof(ULARGE_INTEGER));
133 firstTime = (SYSTEMTIME *)_mp_malloc(sizeof(SYSTEMTIME));
134 firstTime->wYear = 1970;
135 firstTime->wMonth = 1;
136 firstTime->wDayOfWeek = 4;
137 firstTime->wDay = 1;
138 firstTime->wHour = 0;
139 firstTime->wMinute = 0;
140 firstTime->wSecond = 0;
141 firstTime->wMilliseconds = 0;
142
143 firstFileTime = (FILETIME *)_mp_malloc(sizeof(FILETIME));
144 SystemTimeToFileTime(firstTime, firstFileTime);
145 firstLarge->u.LowPart = firstFileTime->dwLowDateTime;
146 firstLarge->u.HighPart = firstFileTime->dwHighDateTime;
147
148 *out =
149 (unsigned int)((fileTime->QuadPart - firstLarge->QuadPart) / 10000000LL);
150
151 _mp_free(firstFileTime);
152 _mp_free(firstTime);
153 _mp_free(firstLarge);
154 }
155
156 void
__UnpackTime(unsigned int secsSince1970,ULARGE_INTEGER * fileTime)157 __UnpackTime(unsigned int secsSince1970, ULARGE_INTEGER *fileTime)
158 {
159
160 FILETIME *firstFileTime;
161 ULARGE_INTEGER *firstLarge;
162 SYSTEMTIME *firstTime;
163
164 firstTime = (SYSTEMTIME *)_mp_malloc(sizeof(SYSTEMTIME));
165 firstTime->wYear = 1970;
166 firstTime->wMonth = 1;
167 firstTime->wDayOfWeek = 4;
168 firstTime->wDay = 1;
169 firstTime->wHour = 0;
170 firstTime->wMinute = 0;
171 firstTime->wSecond = 0;
172 firstTime->wMilliseconds = 0;
173
174 firstFileTime = (FILETIME *)_mp_malloc(sizeof(FILETIME));
175
176 firstLarge = (ULARGE_INTEGER *)_mp_malloc(sizeof(ULARGE_INTEGER));
177 SystemTimeToFileTime(firstTime, firstFileTime);
178 firstLarge->u.LowPart = firstFileTime->dwLowDateTime;
179 firstLarge->u.HighPart = firstFileTime->dwHighDateTime;
180
181 fileTime->QuadPart =
182 ((unsigned long long)secsSince1970 * 10000000LL) + firstLarge->QuadPart;
183
184 _mp_free(firstFileTime);
185 _mp_free(firstTime);
186 _mp_free(firstLarge);
187 }
188
189 #define FILE$FIRST -1
190 #define FILE$LAST -2
191 #define FILE$ERROR -3
192
193 int
__GETFILEINFOQQ(char * ffiles_arg,char * buffer,int * handle,int ffiles_len)194 __GETFILEINFOQQ(char *ffiles_arg, char *buffer, int *handle, int ffiles_len)
195 {
196 char *files;
197 int rslt = 0, i;
198 WIN32_FIND_DATA FindFileData;
199 HANDLE hFind;
200 ULARGE_INTEGER fileTime;
201 char *name;
202 struct FILE$INFO {
203 unsigned int creation;
204 unsigned int lastWrite;
205 unsigned int lastAccess;
206 int length;
207 int permit;
208 char name[256];
209 } fileInfo;
210
211 files = __fstr2cstr(ffiles_arg, ffiles_len);
212 if (!files || !buffer || !handle) {
213 __io_errno();
214 return 0;
215 }
216 if (*handle <= 0) {
217 hFind = FindFirstFile(files, &FindFileData);
218 *handle = (int)hFind;
219 } else {
220 hFind = (HANDLE)*handle;
221 if (FindNextFile(hFind, &FindFileData) == 0) {
222 *handle = FILE$LAST;
223 FindClose(hFind);
224 goto rtn;
225 }
226 }
227
228 if (hFind == INVALID_HANDLE_VALUE) {
229 *handle = FILE$ERROR;
230 goto rtn;
231 }
232
233 fileTime.u.LowPart = FindFileData.ftCreationTime.dwLowDateTime;
234 fileTime.u.HighPart = FindFileData.ftCreationTime.dwHighDateTime;
235 __GetTimeToSecondsSince1970(&fileTime, &(fileInfo.creation));
236
237 fileTime.u.LowPart = FindFileData.ftLastWriteTime.dwLowDateTime;
238 fileTime.u.HighPart = FindFileData.ftLastWriteTime.dwHighDateTime;
239 __GetTimeToSecondsSince1970(&fileTime, &(fileInfo.lastWrite));
240
241 fileTime.u.LowPart = FindFileData.ftLastAccessTime.dwLowDateTime;
242 fileTime.u.HighPart = FindFileData.ftLastAccessTime.dwHighDateTime;
243 __GetTimeToSecondsSince1970(&fileTime, &(fileInfo.lastAccess));
244
245 fileInfo.length = (int)((FindFileData.nFileSizeHigh * (MAXDWORD + 1)) +
246 FindFileData.nFileSizeLow);
247 fileInfo.permit = FindFileData.dwFileAttributes;
248 name = FindFileData.cFileName;
249 rslt = strlen(name);
250
251 __fcp_cstr(fileInfo.name, 255, name);
252 memcpy(buffer, &fileInfo, sizeof(fileInfo));
253 rtn:
254 __cstr_free(files);
255 return rslt;
256 }
257
258 #endif
259