Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjlib / src / pj / file_access_win32.c
1 /* $Id$ */
2 /* 
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
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>
21 #include <pj/unicode.h>
22 #include <pj/assert.h>
23 #include <pj/errno.h>
24 #include <pj/string.h>
25 #include <pj/os.h>
26 #include <windows.h>
27 #include <time.h>
28
29 #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
37 /*
38  * pj_file_exists()
39  */
40 PJ_DEF(pj_bool_t) pj_file_exists(const char *filename)
41 {
42     PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
43     HANDLE hFile;
44
45     PJ_ASSERT_RETURN(filename != NULL, 0);
46
47     hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), 
48                        CONTROL_ACCESS, 
49                        FILE_SHARE_READ, NULL,
50                        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  */
62 PJ_DEF(pj_off_t) pj_file_size(const char *filename)
63 {
64     PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
65     HANDLE hFile;
66     DWORD sizeLo, sizeHi;
67     pj_off_t size;
68
69     PJ_ASSERT_RETURN(filename != NULL, -1);
70
71     hFile = CreateFile(PJ_STRING_TO_NATIVE(filename, wfilename,sizeof(wfilename)), 
72                        CONTROL_ACCESS, 
73                        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  */
98 PJ_DEF(pj_status_t) pj_file_delete(const char *filename)
99 {
100     PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
101
102     PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL);
103
104     if (DeleteFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename))) == FALSE)
105         return PJ_RETURN_OS_ERROR(GetLastError());
106
107     return PJ_SUCCESS;
108 }
109
110
111 /*
112  * pj_file_move()
113  */
114 PJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname)
115 {
116     PJ_DECL_UNICODE_TEMP_BUF(woldname,256)
117     PJ_DECL_UNICODE_TEMP_BUF(wnewname,256)
118     BOOL rc;
119
120     PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL);
121
122 #if PJ_WIN32_WINNT >= 0x0400
123     rc = MoveFileEx(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), 
124                     PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)), 
125                     MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING);
126 #else
127     rc = MoveFile(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), 
128                   PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)));
129 #endif
130
131     if (!rc)
132         return PJ_RETURN_OS_ERROR(GetLastError());
133
134     return PJ_SUCCESS;
135 }
136
137
138 static pj_status_t file_time_to_time_val(const FILETIME *file_time,
139                                          pj_time_val *time_val)
140 {
141     FILETIME local_file_time;
142     SYSTEMTIME localTime;
143     pj_parsed_time pt;
144
145     if (!FileTimeToLocalFileTime(file_time, &local_file_time))
146         return PJ_RETURN_OS_ERROR(GetLastError());
147
148     if (!FileTimeToSystemTime(file_time, &localTime))
149         return PJ_RETURN_OS_ERROR(GetLastError());
150
151     //if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime))
152     //    return PJ_RETURN_OS_ERROR(GetLastError());
153
154     pj_bzero(&pt, sizeof(pt));
155     pt.year = localTime.wYear;
156     pt.mon = localTime.wMonth-1;
157     pt.day = localTime.wDay;
158     pt.wday = localTime.wDayOfWeek;
159
160     pt.hour = localTime.wHour;
161     pt.min = localTime.wMinute;
162     pt.sec = localTime.wSecond;
163     pt.msec = localTime.wMilliseconds;
164
165     return pj_time_encode(&pt, time_val);
166 }
167
168 /*
169  * pj_file_getstat()
170  */
171 PJ_DEF(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat)
172 {
173     PJ_DECL_UNICODE_TEMP_BUF(wfilename,256)
174     HANDLE hFile;
175     DWORD sizeLo, sizeHi;
176     FILETIME creationTime, accessTime, writeTime;
177
178     PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL);
179
180     hFile = CreateFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename)), 
181                        CONTROL_ACCESS, 
182                        FILE_SHARE_READ, NULL,
183                        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