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