/* $Id$ */ /* * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) * Copyright (C) 2003-2008 Benny Prijono * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0 /* WinCE lacks READ_CONTROL so we must use GENERIC_READ */ # define CONTROL_ACCESS GENERIC_READ #else # define CONTROL_ACCESS READ_CONTROL #endif static pj_status_t get_file_size(HANDLE hFile, pj_off_t *size) { #if defined(PJ_WIN32_WINPHONE8) && PJ_WIN32_WINPHONE8 FILE_COMPRESSION_INFO fileInfo; if (GetFileInformationByHandleEx(hFile, FileCompressionInfo, &fileInfo, sizeof(FILE_COMPRESSION_INFO))) { *size = fileInfo.CompressedFileSize.QuadPart; } else { *size = -1; return PJ_RETURN_OS_ERROR(GetLastError()); } #else DWORD sizeLo, sizeHi; sizeLo = GetFileSize(hFile, &sizeHi); if (sizeLo == INVALID_FILE_SIZE) { DWORD dwStatus = GetLastError(); if (dwStatus != NO_ERROR) { *size = -1; return PJ_RETURN_OS_ERROR(dwStatus); } } *size = sizeHi; *size = ((*size) << 32) + sizeLo; #endif return PJ_SUCCESS; } static HANDLE WINAPI create_file(LPCTSTR filename, DWORD desired_access, DWORD share_mode, LPSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD flags_and_attributes, HANDLE template_file) { #if defined(PJ_WIN32_WINPHONE8) && PJ_WIN32_WINPHONE8 PJ_UNUSED_ARG(security_attributes); PJ_UNUSED_ARG(flags_and_attributes); PJ_UNUSED_ARG(template_file); return CreateFile2(filename, desired_access, share_mode, creation_disposition, NULL); #else return CreateFile(filename, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file); #endif } /* * pj_file_exists() */ PJ_DEF(pj_bool_t) pj_file_exists(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; PJ_ASSERT_RETURN(filename != NULL, 0); hFile = create_file(PJ_STRING_TO_NATIVE(filename, wfilename, sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return 0; CloseHandle(hFile); return PJ_TRUE; } /* * pj_file_size() */ PJ_DEF(pj_off_t) pj_file_size(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; pj_off_t size; PJ_ASSERT_RETURN(filename != NULL, -1); hFile = create_file(PJ_STRING_TO_NATIVE(filename, wfilename, sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return -1; get_file_size(hFile, &size); CloseHandle(hFile); return size; } /* * pj_file_delete() */ PJ_DEF(pj_status_t) pj_file_delete(const char *filename) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL); if (DeleteFile(PJ_STRING_TO_NATIVE(filename,wfilename,sizeof(wfilename))) == FALSE) return PJ_RETURN_OS_ERROR(GetLastError()); return PJ_SUCCESS; } /* * pj_file_move() */ PJ_DEF(pj_status_t) pj_file_move( const char *oldname, const char *newname) { PJ_DECL_UNICODE_TEMP_BUF(woldname,256) PJ_DECL_UNICODE_TEMP_BUF(wnewname,256) BOOL rc; PJ_ASSERT_RETURN(oldname!=NULL && newname!=NULL, PJ_EINVAL); #if PJ_WIN32_WINNT >= 0x0400 rc = MoveFileEx(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname)), MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING); #else rc = MoveFile(PJ_STRING_TO_NATIVE(oldname,woldname,sizeof(woldname)), PJ_STRING_TO_NATIVE(newname,wnewname,sizeof(wnewname))); #endif if (!rc) return PJ_RETURN_OS_ERROR(GetLastError()); return PJ_SUCCESS; } static pj_status_t file_time_to_time_val(const FILETIME *file_time, pj_time_val *time_val) { #if !defined(PJ_WIN32_WINPHONE8) || !PJ_WIN32_WINPHONE8 FILETIME local_file_time; #endif SYSTEMTIME localTime; pj_parsed_time pt; #if !defined(PJ_WIN32_WINPHONE8) || !PJ_WIN32_WINPHONE8 if (!FileTimeToLocalFileTime(file_time, &local_file_time)) return PJ_RETURN_OS_ERROR(GetLastError()); #endif if (!FileTimeToSystemTime(file_time, &localTime)) return PJ_RETURN_OS_ERROR(GetLastError()); //if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime)) // return PJ_RETURN_OS_ERROR(GetLastError()); pj_bzero(&pt, sizeof(pt)); pt.year = localTime.wYear; pt.mon = localTime.wMonth-1; pt.day = localTime.wDay; pt.wday = localTime.wDayOfWeek; pt.hour = localTime.wHour; pt.min = localTime.wMinute; pt.sec = localTime.wSecond; pt.msec = localTime.wMilliseconds; return pj_time_encode(&pt, time_val); } /* * pj_file_getstat() */ PJ_DEF(pj_status_t) pj_file_getstat(const char *filename, pj_file_stat *stat) { PJ_DECL_UNICODE_TEMP_BUF(wfilename,256) HANDLE hFile; FILETIME creationTime, accessTime, writeTime; #if defined(PJ_WIN32_WINPHONE8) && PJ_WIN32_WINPHONE8 FILE_BASIC_INFO fileInfo; #endif PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL); hFile = create_file(PJ_STRING_TO_NATIVE(filename, wfilename, sizeof(wfilename)), CONTROL_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return PJ_RETURN_OS_ERROR(GetLastError()); if (get_file_size(hFile, &stat->size) != PJ_SUCCESS) { CloseHandle(hFile); return PJ_RETURN_OS_ERROR(GetLastError()); } #if defined(PJ_WIN32_WINPHONE8) && PJ_WIN32_WINPHONE8 if (GetFileInformationByHandleEx(hFile, FileBasicInfo, &fileInfo, sizeof(FILE_BASIC_INFO))) { creationTime.dwLowDateTime = fileInfo.CreationTime.LowPart; creationTime.dwHighDateTime = fileInfo.CreationTime.HighPart; accessTime.dwLowDateTime = fileInfo.LastAccessTime.LowPart; accessTime.dwHighDateTime = fileInfo.LastAccessTime.HighPart; writeTime.dwLowDateTime = fileInfo.LastWriteTime.LowPart; writeTime.dwHighDateTime = fileInfo.LastWriteTime.HighPart; } else { CloseHandle(hFile); return PJ_RETURN_OS_ERROR(GetLastError()); } #else if (GetFileTime(hFile, &creationTime, &accessTime, &writeTime) == FALSE) { DWORD dwStatus = GetLastError(); CloseHandle(hFile); return PJ_RETURN_OS_ERROR(dwStatus); } #endif CloseHandle(hFile); if (file_time_to_time_val(&creationTime, &stat->ctime) != PJ_SUCCESS) return PJ_RETURN_OS_ERROR(GetLastError()); file_time_to_time_val(&accessTime, &stat->atime); file_time_to_time_val(&writeTime, &stat->mtime); return PJ_SUCCESS; }