blob: 7281b0223f9a6d0b98de2a94d9f550b9eb31230a [file] [log] [blame]
/* $Id$ */
/*
* Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
*
* 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 <pj/file_access.h>
#include <pj/unicode.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/string.h>
#include <pj/os.h>
#include <windows.h>
#include <time.h>
#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
/*
* 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 = CreateFile(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;
DWORD sizeLo, sizeHi;
pj_off_t size;
PJ_ASSERT_RETURN(filename != NULL, -1);
hFile = CreateFile(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;
sizeLo = GetFileSize(hFile, &sizeHi);
if (sizeLo == INVALID_FILE_SIZE) {
DWORD dwStatus = GetLastError();
if (dwStatus != NO_ERROR) {
CloseHandle(hFile);
return -1;
}
}
size = sizeHi;
size = (size << 32) + sizeLo;
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)
{
FILETIME local_file_time;
SYSTEMTIME localTime;
pj_parsed_time pt;
if (!FileTimeToLocalFileTime(file_time, &local_file_time))
return PJ_RETURN_OS_ERROR(GetLastError());
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;
DWORD sizeLo, sizeHi;
FILETIME creationTime, accessTime, writeTime;
PJ_ASSERT_RETURN(filename!=NULL && stat!=NULL, PJ_EINVAL);
hFile = CreateFile(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());
sizeLo = GetFileSize(hFile, &sizeHi);
if (sizeLo == INVALID_FILE_SIZE) {
DWORD dwStatus = GetLastError();
if (dwStatus != NO_ERROR) {
CloseHandle(hFile);
return PJ_RETURN_OS_ERROR(dwStatus);
}
}
stat->size = sizeHi;
stat->size = (stat->size << 32) + sizeLo;
if (GetFileTime(hFile, &creationTime, &accessTime, &writeTime)==FALSE) {
DWORD dwStatus = GetLastError();
CloseHandle(hFile);
return PJ_RETURN_OS_ERROR(dwStatus);
}
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;
}