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 /* clang-format off */
19 
20 /*	setfiletimeqq3f.c - Implements DFLIB setfiletimeqq subprogram.  */
21 #if defined(WIN64) || defined(WIN32)
22 #include <windows.h>
23 #endif
24 #include <string.h>
25 #include <stdlib.h>
26 /* must include ent3f.h AFTER io3f.h */
27 #include "io3f.h"
28 #include "ent3f.h"
29 
30 #define FILE$FIRST -1
31 #define FILE$LAST -2
32 #define FILE$ERROR -3
33 #define FILE$CURTIME -1
34 
35 #if defined(WIN64) || defined(WIN32)
36 extern char *__fstr2cstr();
37 extern void __UnpackTime(unsigned int secsSince1970, ULARGE_INTEGER *fileTime);
38 extern int __GETFILEINFOQQ(DCHAR(ffiles), char *buffer,
39                            int *handle DCLEN(ffiles));
ENT3F(SETFILETIMEQQ,setfiletimeqq)40 int ENT3F(SETFILETIMEQQ, setfiletimeqq)(DCHAR(ffile),
41                                         unsigned int *timedate DCLEN(ffile))
42 {
43 
44   HANDLE handle;
45   char *fileName = 0;
46   int rslt = 0, success;
47   ULARGE_INTEGER *fileTime = 0;
48   struct FILE$INFO {
49     int creation;
50     int lastWrite;
51     int lastAccess;
52     int length;
53     int permit;
54     char name[256];
55   } fileInfo, fileInfo2;
56   FILETIME *creation = 0, *lastAccess = 0, *lastWrite = 0;
57 
58   fileTime = (ULARGE_INTEGER *)_mp_malloc(sizeof(ULARGE_INTEGER));
59   if (*timedate == FILE$CURTIME) {
60     SYSTEMTIME *sysTime;
61     sysTime = (SYSTEMTIME *)_mp_malloc(sizeof(SYSTEMTIME));
62     GetSystemTime(sysTime);
63     lastWrite = (FILETIME *)_mp_malloc(sizeof(FILETIME));
64     SystemTimeToFileTime(sysTime, lastWrite);
65     _mp_free(sysTime);
66   } else {
67     __UnpackTime(*timedate, fileTime);
68     lastWrite = (FILETIME *)_mp_malloc(sizeof(FILETIME));
69     lastWrite->dwLowDateTime = fileTime->u.LowPart;
70     lastWrite->dwHighDateTime = fileTime->u.HighPart;
71   }
72 
73   handle = FILE$FIRST;
74   __GETFILEINFOQQ(CADR(ffile), (char *)&fileInfo, (int *)&handle, CLEN(ffile));
75   while ((int)handle >= 0) {
76     __GETFILEINFOQQ(CADR(ffile), (char *)&fileInfo2, (int *)&handle,
77                     CLEN(ffile));
78   }
79 
80   if ((int)handle == FILE$LAST) {
81     fileName = __fstr2cstr(CADR(ffile), CLEN(ffile));
82     if (!fileName)
83       return 0;
84 
85     handle = CreateFile(fileName, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
86                         fileInfo.permit, 0);
87 
88     if (handle == INVALID_HANDLE_VALUE)
89       goto rtn;
90 
91     __UnpackTime(fileInfo.creation, fileTime);
92     creation = (FILETIME *)_mp_malloc(sizeof(FILETIME));
93     creation->dwLowDateTime = fileTime->u.LowPart;
94     creation->dwHighDateTime = fileTime->u.HighPart;
95 
96     __UnpackTime(fileInfo.lastAccess, fileTime);
97     lastAccess = (FILETIME *)_mp_malloc(sizeof(FILETIME));
98     lastAccess->dwLowDateTime = fileTime->u.LowPart;
99     lastAccess->dwHighDateTime = fileTime->u.HighPart;
100 
101     success = SetFileTime(handle, creation, lastAccess, lastWrite);
102     if (success) {
103       rslt = -1;
104     }
105     CloseHandle(handle);
106   }
107 
108 rtn:
109   if (fileName)
110     __cstr_free(fileName);
111   _mp_free(fileTime);
112   _mp_free(lastWrite);
113   _mp_free(lastAccess);
114   _mp_free(creation);
115   return rslt;
116 }
117 #else
ENT3F(SETFILETIMEQQ,setfiletimeqq)118 int ENT3F(SETFILETIMEQQ, setfiletimeqq)(DCHAR(ffile),
119                                         unsigned int *timedate DCLEN(ffile))
120 {
121   fprintf(__io_stderr(), "setfiletimeqq() not implemented on this target\n");
122   return 0;
123 }
124 
125 #endif
126