blob: 47abad4ac70c03dbfb1e0bb99ba753c2eb9e13e9 [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pj/file_access.h>
Benny Prijono37e8d332006-01-20 21:03:36 +000020#include <pj/unicode.h>
Benny Prijono9033e312005-11-21 02:08:39 +000021#include <pj/assert.h>
22#include <pj/errno.h>
Benny Prijono9cf138e2006-01-19 03:58:29 +000023#include <pj/string.h>
24#include <pj/os.h>
Benny Prijono9033e312005-11-21 02:08:39 +000025#include <windows.h>
26#include <time.h>
27
28/*
29 * pj_file_exists()
30 */
31PJ_DEF(pj_bool_t) pj_file_exists(const char *filename)
32{
Benny Prijono61396412006-02-14 21:03:15 +000033 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9033e312005-11-21 02:08:39 +000034 HANDLE hFile;
35
36 PJ_ASSERT_RETURN(filename != NULL, 0);
37
Benny Prijono61396412006-02-14 21:03:15 +000038 hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)),
39 READ_CONTROL,
Benny Prijono9cf138e2006-01-19 03:58:29 +000040 FILE_SHARE_READ, NULL,
Benny Prijono9033e312005-11-21 02:08:39 +000041 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
42 if (hFile == INVALID_HANDLE_VALUE)
43 return 0;
44
45 CloseHandle(hFile);
46 return PJ_TRUE;
47}
48
49
50/*
51 * pj_file_size()
52 */
53PJ_DEF(pj_off_t) pj_file_size(const char *filename)
54{
Benny Prijono61396412006-02-14 21:03:15 +000055 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9033e312005-11-21 02:08:39 +000056 HANDLE hFile;
57 DWORD sizeLo, sizeHi;
58 pj_off_t size;
59
60 PJ_ASSERT_RETURN(filename != NULL, -1);
61
Benny Prijono61396412006-02-14 21:03:15 +000062 hFile = CreateFile(PJ_STRING_TO_NATIVE(filename, wfilename,sizeof(wfilename)),
63 READ_CONTROL,
Benny Prijono9033e312005-11-21 02:08:39 +000064 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
65 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
66 if (hFile == INVALID_HANDLE_VALUE)
67 return -1;
68
69 sizeLo = GetFileSize(hFile, &sizeHi);
70 if (sizeLo == INVALID_FILE_SIZE) {
71 DWORD dwStatus = GetLastError();
72 if (dwStatus != NO_ERROR) {
73 CloseHandle(hFile);
74 return -1;
75 }
76 }
77
78 size = sizeHi;
79 size = (size << 32) + sizeLo;
80
81 CloseHandle(hFile);
82 return size;
83}
84
85
86/*
87 * pj_file_delete()
88 */
89PJ_DEF(pj_status_t) pj_file_delete(const char *filename)
90{
Benny Prijono61396412006-02-14 21:03:15 +000091 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9cf138e2006-01-19 03:58:29 +000092
Benny Prijono9033e312005-11-21 02:08:39 +000093 PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL);
94
Benny Prijono61396412006-02-14 21:03:15 +000095 if (DeleteFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename))) == FALSE)
Benny Prijono9033e312005-11-21 02:08:39 +000096 return PJ_RETURN_OS_ERROR(GetLastError());
97
98 return PJ_SUCCESS;
99}
100
101
102/*
103 * pj_file_move()
104 */
105PJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname)
106{
Benny Prijono61396412006-02-14 21:03:15 +0000107 PJ_DECL_UNICODE_TEMP_BUF(woldname,256)
108 PJ_DECL_UNICODE_TEMP_BUF(wnewname,256)
Benny Prijono9033e312005-11-21 02:08:39 +0000109 BOOL rc;
110
111 PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL);
112
113#if PJ_WIN32_WINNT >= 0x0400
Benny Prijono61396412006-02-14 21:03:15 +0000114 rc = MoveFileEx(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)),
115 PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)),
Benny Prijono9033e312005-11-21 02:08:39 +0000116 MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING);
117#else
Benny Prijono61396412006-02-14 21:03:15 +0000118 rc = MoveFile(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)),
119 PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)));
Benny Prijono9033e312005-11-21 02:08:39 +0000120#endif
121
122 if (!rc)
123 return PJ_RETURN_OS_ERROR(GetLastError());
124
125 return PJ_SUCCESS;
126}
127
128
129static pj_status_t file_time_to_time_val(const FILETIME *file_time,
130 pj_time_val *time_val)
131{
Benny Prijono9cf138e2006-01-19 03:58:29 +0000132 FILETIME local_file_time;
133 SYSTEMTIME localTime;
134 pj_parsed_time pt;
Benny Prijono9033e312005-11-21 02:08:39 +0000135
Benny Prijono9cf138e2006-01-19 03:58:29 +0000136 if (!FileTimeToLocalFileTime(file_time, &local_file_time))
137 return PJ_RETURN_OS_ERROR(GetLastError());
Benny Prijono9033e312005-11-21 02:08:39 +0000138
Benny Prijono9cf138e2006-01-19 03:58:29 +0000139 if (!FileTimeToSystemTime(file_time, &localTime))
140 return PJ_RETURN_OS_ERROR(GetLastError());
Benny Prijono9033e312005-11-21 02:08:39 +0000141
Benny Prijono9cf138e2006-01-19 03:58:29 +0000142 //if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime))
143 // return PJ_RETURN_OS_ERROR(GetLastError());
Benny Prijono9033e312005-11-21 02:08:39 +0000144
Benny Prijonoac623b32006-07-03 15:19:31 +0000145 pj_bzero(&pt, sizeof(pt));
Benny Prijono9cf138e2006-01-19 03:58:29 +0000146 pt.year = localTime.wYear;
147 pt.mon = localTime.wMonth-1;
148 pt.day = localTime.wDay;
149 pt.wday = localTime.wDayOfWeek;
Benny Prijono9033e312005-11-21 02:08:39 +0000150
Benny Prijono9cf138e2006-01-19 03:58:29 +0000151 pt.hour = localTime.wHour;
152 pt.min = localTime.wMinute;
153 pt.sec = localTime.wSecond;
154 pt.msec = localTime.wMilliseconds;
Benny Prijono9033e312005-11-21 02:08:39 +0000155
Benny Prijono9cf138e2006-01-19 03:58:29 +0000156 return pj_time_encode(&pt, time_val);
Benny Prijono9033e312005-11-21 02:08:39 +0000157}
158
159/*
160 * pj_file_getstat()
161 */
162PJ_DEF(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat)
163{
Benny Prijono61396412006-02-14 21:03:15 +0000164 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9033e312005-11-21 02:08:39 +0000165 HANDLE hFile;
166 DWORD sizeLo, sizeHi;
167 FILETIME creationTime, accessTime, writeTime;
168
169 PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL);
170
Benny Prijono61396412006-02-14 21:03:15 +0000171 hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)),
172 READ_CONTROL,
Benny Prijono9cf138e2006-01-19 03:58:29 +0000173 FILE_SHARE_READ, NULL,
Benny Prijono9033e312005-11-21 02:08:39 +0000174 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
175 if (hFile == INVALID_HANDLE_VALUE)
176 return PJ_RETURN_OS_ERROR(GetLastError());
177
178 sizeLo = GetFileSize(hFile, &sizeHi);
179 if (sizeLo == INVALID_FILE_SIZE) {
180 DWORD dwStatus = GetLastError();
181 if (dwStatus != NO_ERROR) {
182 CloseHandle(hFile);
183 return PJ_RETURN_OS_ERROR(dwStatus);
184 }
185 }
186
187 stat->size = sizeHi;
188 stat->size = (stat->size << 32) + sizeLo;
189
190 if (GetFileTime(hFile, &creationTime, &accessTime, &writeTime)==FALSE) {
191 DWORD dwStatus = GetLastError();
192 CloseHandle(hFile);
193 return PJ_RETURN_OS_ERROR(dwStatus);
194 }
195
196 CloseHandle(hFile);
197
198 if (file_time_to_time_val(&creationTime, &stat->ctime) != PJ_SUCCESS)
199 return PJ_RETURN_OS_ERROR(GetLastError());
200
201 file_time_to_time_val(&accessTime, &stat->atime);
202 file_time_to_time_val(&writeTime, &stat->mtime);
203
204 return PJ_SUCCESS;
205}
206