blob: 21fad4ebc146dcd1d781ad8b2f720cb4172df8d1 [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <pj/file_access.h>
Benny Prijono37e8d332006-01-20 21:03:36 +000021#include <pj/unicode.h>
Benny Prijono9033e312005-11-21 02:08:39 +000022#include <pj/assert.h>
23#include <pj/errno.h>
Benny Prijono9cf138e2006-01-19 03:58:29 +000024#include <pj/string.h>
25#include <pj/os.h>
Benny Prijono9033e312005-11-21 02:08:39 +000026#include <windows.h>
27#include <time.h>
28
Benny Prijonodfdfc212007-06-22 11:30:44 +000029#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
30 /* WinCE lacks READ_CONTROL so we must use GENERIC_READ */
31# define CONTROL_ACCESS GENERIC_READ
32#else
33# define CONTROL_ACCESS READ_CONTROL
34#endif
35
36
Benny Prijono9033e312005-11-21 02:08:39 +000037/*
38 * pj_file_exists()
39 */
40PJ_DEF(pj_bool_t) pj_file_exists(const char *filename)
41{
Benny Prijono61396412006-02-14 21:03:15 +000042 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9033e312005-11-21 02:08:39 +000043 HANDLE hFile;
44
45 PJ_ASSERT_RETURN(filename != NULL, 0);
46
Benny Prijono61396412006-02-14 21:03:15 +000047 hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)),
Benny Prijonodfdfc212007-06-22 11:30:44 +000048 CONTROL_ACCESS,
Benny Prijono9cf138e2006-01-19 03:58:29 +000049 FILE_SHARE_READ, NULL,
Benny Prijono9033e312005-11-21 02:08:39 +000050 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
51 if (hFile == INVALID_HANDLE_VALUE)
52 return 0;
53
54 CloseHandle(hFile);
55 return PJ_TRUE;
56}
57
58
59/*
60 * pj_file_size()
61 */
62PJ_DEF(pj_off_t) pj_file_size(const char *filename)
63{
Benny Prijono61396412006-02-14 21:03:15 +000064 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9033e312005-11-21 02:08:39 +000065 HANDLE hFile;
66 DWORD sizeLo, sizeHi;
67 pj_off_t size;
68
69 PJ_ASSERT_RETURN(filename != NULL, -1);
70
Benny Prijono61396412006-02-14 21:03:15 +000071 hFile = CreateFile(PJ_STRING_TO_NATIVE(filename, wfilename,sizeof(wfilename)),
Benny Prijonodfdfc212007-06-22 11:30:44 +000072 CONTROL_ACCESS,
Benny Prijono9033e312005-11-21 02:08:39 +000073 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
74 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
75 if (hFile == INVALID_HANDLE_VALUE)
76 return -1;
77
78 sizeLo = GetFileSize(hFile, &sizeHi);
79 if (sizeLo == INVALID_FILE_SIZE) {
80 DWORD dwStatus = GetLastError();
81 if (dwStatus != NO_ERROR) {
82 CloseHandle(hFile);
83 return -1;
84 }
85 }
86
87 size = sizeHi;
88 size = (size << 32) + sizeLo;
89
90 CloseHandle(hFile);
91 return size;
92}
93
94
95/*
96 * pj_file_delete()
97 */
98PJ_DEF(pj_status_t) pj_file_delete(const char *filename)
99{
Benny Prijono61396412006-02-14 21:03:15 +0000100 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9cf138e2006-01-19 03:58:29 +0000101
Benny Prijono9033e312005-11-21 02:08:39 +0000102 PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL);
103
Benny Prijono61396412006-02-14 21:03:15 +0000104 if (DeleteFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename))) == FALSE)
Benny Prijono9033e312005-11-21 02:08:39 +0000105 return PJ_RETURN_OS_ERROR(GetLastError());
106
107 return PJ_SUCCESS;
108}
109
110
111/*
112 * pj_file_move()
113 */
114PJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname)
115{
Benny Prijono61396412006-02-14 21:03:15 +0000116 PJ_DECL_UNICODE_TEMP_BUF(woldname,256)
117 PJ_DECL_UNICODE_TEMP_BUF(wnewname,256)
Benny Prijono9033e312005-11-21 02:08:39 +0000118 BOOL rc;
119
120 PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL);
121
122#if PJ_WIN32_WINNT >= 0x0400
Benny Prijono61396412006-02-14 21:03:15 +0000123 rc = MoveFileEx(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)),
124 PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)),
Benny Prijono9033e312005-11-21 02:08:39 +0000125 MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING);
126#else
Benny Prijono61396412006-02-14 21:03:15 +0000127 rc = MoveFile(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)),
128 PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)));
Benny Prijono9033e312005-11-21 02:08:39 +0000129#endif
130
131 if (!rc)
132 return PJ_RETURN_OS_ERROR(GetLastError());
133
134 return PJ_SUCCESS;
135}
136
137
138static pj_status_t file_time_to_time_val(const FILETIME *file_time,
139 pj_time_val *time_val)
140{
Benny Prijono9cf138e2006-01-19 03:58:29 +0000141 FILETIME local_file_time;
142 SYSTEMTIME localTime;
143 pj_parsed_time pt;
Benny Prijono9033e312005-11-21 02:08:39 +0000144
Benny Prijono9cf138e2006-01-19 03:58:29 +0000145 if (!FileTimeToLocalFileTime(file_time, &local_file_time))
146 return PJ_RETURN_OS_ERROR(GetLastError());
Benny Prijono9033e312005-11-21 02:08:39 +0000147
Benny Prijono9cf138e2006-01-19 03:58:29 +0000148 if (!FileTimeToSystemTime(file_time, &localTime))
149 return PJ_RETURN_OS_ERROR(GetLastError());
Benny Prijono9033e312005-11-21 02:08:39 +0000150
Benny Prijono9cf138e2006-01-19 03:58:29 +0000151 //if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime))
152 // return PJ_RETURN_OS_ERROR(GetLastError());
Benny Prijono9033e312005-11-21 02:08:39 +0000153
Benny Prijonoac623b32006-07-03 15:19:31 +0000154 pj_bzero(&pt, sizeof(pt));
Benny Prijono9cf138e2006-01-19 03:58:29 +0000155 pt.year = localTime.wYear;
156 pt.mon = localTime.wMonth-1;
157 pt.day = localTime.wDay;
158 pt.wday = localTime.wDayOfWeek;
Benny Prijono9033e312005-11-21 02:08:39 +0000159
Benny Prijono9cf138e2006-01-19 03:58:29 +0000160 pt.hour = localTime.wHour;
161 pt.min = localTime.wMinute;
162 pt.sec = localTime.wSecond;
163 pt.msec = localTime.wMilliseconds;
Benny Prijono9033e312005-11-21 02:08:39 +0000164
Benny Prijono9cf138e2006-01-19 03:58:29 +0000165 return pj_time_encode(&pt, time_val);
Benny Prijono9033e312005-11-21 02:08:39 +0000166}
167
168/*
169 * pj_file_getstat()
170 */
171PJ_DEF(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat)
172{
Benny Prijono61396412006-02-14 21:03:15 +0000173 PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
Benny Prijono9033e312005-11-21 02:08:39 +0000174 HANDLE hFile;
175 DWORD sizeLo, sizeHi;
176 FILETIME creationTime, accessTime, writeTime;
177
178 PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL);
179
Benny Prijono61396412006-02-14 21:03:15 +0000180 hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)),
Benny Prijonodfdfc212007-06-22 11:30:44 +0000181 CONTROL_ACCESS,
Benny Prijono9cf138e2006-01-19 03:58:29 +0000182 FILE_SHARE_READ, NULL,
Benny Prijono9033e312005-11-21 02:08:39 +0000183 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
184 if (hFile == INVALID_HANDLE_VALUE)
185 return PJ_RETURN_OS_ERROR(GetLastError());
186
187 sizeLo = GetFileSize(hFile, &sizeHi);
188 if (sizeLo == INVALID_FILE_SIZE) {
189 DWORD dwStatus = GetLastError();
190 if (dwStatus != NO_ERROR) {
191 CloseHandle(hFile);
192 return PJ_RETURN_OS_ERROR(dwStatus);
193 }
194 }
195
196 stat->size = sizeHi;
197 stat->size = (stat->size << 32) + sizeLo;
198
199 if (GetFileTime(hFile, &creationTime, &accessTime, &writeTime)==FALSE) {
200 DWORD dwStatus = GetLastError();
201 CloseHandle(hFile);
202 return PJ_RETURN_OS_ERROR(dwStatus);
203 }
204
205 CloseHandle(hFile);
206
207 if (file_time_to_time_val(&creationTime, &stat->ctime) != PJ_SUCCESS)
208 return PJ_RETURN_OS_ERROR(GetLastError());
209
210 file_time_to_time_val(&accessTime, &stat->atime);
211 file_time_to_time_val(&writeTime, &stat->mtime);
212
213 return PJ_SUCCESS;
214}
215