home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
mfc
/
src
/
filest.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-16
|
8KB
|
285 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include <errno.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#ifdef AFX_CORE1_SEG
#pragma code_seg(AFX_CORE1_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
////////////////////////////////////////////////////////////////////////////
// Status information for all file classes
// In this file so everyone doesn't get the CTime package
/////////////////////////////////////////////////////////////////////////////
// CFileStatus diagnostics
#ifdef _DEBUG
void CFileStatus::Dump(CDumpContext& dc) const
{
dc << "a CFileStatus at " << (void*)this;
dc << "\nm_ctime = " << m_ctime;
dc << "\nm_mtime = " << m_mtime;
dc << "\nm_atime = " << m_atime;
dc << "\nm_size = " << m_size;
dc << "\nm_attribute = " << m_attribute;
dc << "\nm_szFullName = " << m_szFullName;
dc << "\n";
}
#endif
/////////////////////////////////////////////////////////////////////////////
// CFile name handlers
CString CFile::GetFileName() const
{
ASSERT_VALID(this);
CFileStatus status;
GetStatus(status);
CString strResult;
AfxGetFileName(status.m_szFullName, strResult.GetBuffer(_MAX_FNAME),
_MAX_FNAME);
strResult.ReleaseBuffer();
return strResult;
}
CString CFile::GetFileTitle() const
{
ASSERT_VALID(this);
CFileStatus status;
GetStatus(status);
CString strResult;
AfxGetFileTitle(status.m_szFullName, strResult.GetBuffer(_MAX_FNAME),
_MAX_FNAME);
strResult.ReleaseBuffer();
return strResult;
}
CString CFile::GetFilePath() const
{
ASSERT_VALID(this);
CFileStatus status;
GetStatus(status);
return status.m_szFullName;
}
/////////////////////////////////////////////////////////////////////////////
// CFile Status implementation
BOOL CFile::GetStatus(CFileStatus& rStatus) const
{
ASSERT_VALID(this);
memset(&rStatus, 0, sizeof(CFileStatus));
// copy file name from cached m_strFileName
lstrcpyn(rStatus.m_szFullName, m_strFileName,
_countof(rStatus.m_szFullName));
if (m_hFile != hFileNull)
{
// get time current file size
FILETIME ftCreate, ftAccess, ftModify;
if (!::GetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify))
return FALSE;
if ((rStatus.m_size = ::GetFileSize((HANDLE)m_hFile, NULL)) == (DWORD)-1L)
return FALSE;
if (m_strFileName.IsEmpty())
rStatus.m_attribute = 0;
else
{
DWORD dwAttribute = ::GetFileAttributes(m_strFileName);
// don't return an error for this because previous versions of MFC didn't
if (dwAttribute == 0xFFFFFFFF)
rStatus.m_attribute = 0;
else
{
rStatus.m_attribute = (BYTE) dwAttribute;
#ifdef _DEBUG
// MFC BUG: m_attribute is only a BYTE wide
if (dwAttribute & ~0xFF)
TRACE0("Warning: CFile::GetStatus() returns m_attribute without high-order flags.\n");
#endif
}
}
// convert times as appropriate
rStatus.m_ctime = CTime(ftCreate);
rStatus.m_atime = CTime(ftAccess);
rStatus.m_mtime = CTime(ftModify);
if (rStatus.m_ctime.GetTime() == 0)
rStatus.m_ctime = rStatus.m_mtime;
if (rStatus.m_atime.GetTime() == 0)
rStatus.m_atime = rStatus.m_mtime;
}
return TRUE;
}
BOOL PASCAL CFile::GetStatus(LPCTSTR lpszFileName, CFileStatus& rStatus)
{
// attempt to fully qualify path first
if (!AfxFullPath(rStatus.m_szFullName, lpszFileName))
{
rStatus.m_szFullName[0] = '\0';
return FALSE;
}
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile((LPTSTR)lpszFileName, &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
return FALSE;
VERIFY(FindClose(hFind));
// strip attribute of NORMAL bit, our API doesn't have a "normal" bit.
rStatus.m_attribute = (BYTE)
(findFileData.dwFileAttributes & ~FILE_ATTRIBUTE_NORMAL);
// get just the low DWORD of the file size
ASSERT(findFileData.nFileSizeHigh == 0);
rStatus.m_size = (LONG)findFileData.nFileSizeLow;
// convert times as appropriate
rStatus.m_ctime = CTime(findFileData.ftCreationTime);
rStatus.m_atime = CTime(findFileData.ftLastAccessTime);
rStatus.m_mtime = CTime(findFileData.ftLastWriteTime);
if (rStatus.m_ctime.GetTime() == 0)
rStatus.m_ctime = rStatus.m_mtime;
if (rStatus.m_atime.GetTime() == 0)
rStatus.m_atime = rStatus.m_mtime;
return TRUE;
}
void AFX_CDECL AfxTimeToFileTime(const CTime& time, LPFILETIME pFileTime)
{
SYSTEMTIME sysTime;
sysTime.wYear = (WORD)time.GetYear();
sysTime.wMonth = (WORD)time.GetMonth();
sysTime.wDay = (WORD)time.GetDay();
sysTime.wHour = (WORD)time.GetHour();
sysTime.wMinute = (WORD)time.GetMinute();
sysTime.wSecond = (WORD)time.GetSecond();
sysTime.wMilliseconds = 0;
// convert system time to local file time
FILETIME localTime;
if (!SystemTimeToFileTime((LPSYSTEMTIME)&sysTime, &localTime))
CFileException::ThrowOsError((LONG)::GetLastError());
// convert local file time to UTC file time
if (!LocalFileTimeToFileTime(&localTime, pFileTime))
CFileException::ThrowOsError((LONG)::GetLastError());
}
void PASCAL CFile::SetStatus(LPCTSTR lpszFileName, const CFileStatus& status)
{
DWORD wAttr;
FILETIME creationTime;
FILETIME lastAccessTime;
FILETIME lastWriteTime;
LPFILETIME lpCreationTime = NULL;
LPFILETIME lpLastAccessTime = NULL;
LPFILETIME lpLastWriteTime = NULL;
if ((wAttr = GetFileAttributes((LPTSTR)lpszFileName)) == (DWORD)-1L)
CFileException::ThrowOsError((LONG)GetLastError());
if ((DWORD)status.m_attribute != wAttr && (wAttr & readOnly))
{
// Set file attribute, only if currently readonly.
// This way we will be able to modify the time assuming the
// caller changed the file from readonly.
if (!SetFileAttributes((LPTSTR)lpszFileName, (DWORD)status.m_attribute))
CFileException::ThrowOsError((LONG)GetLastError());
}
// last modification time
if (status.m_mtime.GetTime() != 0)
{
AfxTimeToFileTime(status.m_mtime, &lastWriteTime);
lpLastWriteTime = &lastWriteTime;
// last access time
if (status.m_atime.GetTime() != 0)
{
AfxTimeToFileTime(status.m_atime, &lastAccessTime);
lpLastAccessTime = &lastAccessTime;
}
// create time
if (status.m_ctime.GetTime() != 0)
{
AfxTimeToFileTime(status.m_ctime, &creationTime);
lpCreationTime = &creationTime;
}
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
CFileException::ThrowOsError((LONG)::GetLastError());
if (!SetFileTime((HANDLE)hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime))
CFileException::ThrowOsError((LONG)::GetLastError());
if (!::CloseHandle(hFile))
CFileException::ThrowOsError((LONG)::GetLastError());
}
if ((DWORD)status.m_attribute != wAttr && !(wAttr & readOnly))
{
if (!SetFileAttributes((LPTSTR)lpszFileName, (DWORD)status.m_attribute))
CFileException::ThrowOsError((LONG)GetLastError());
}
}
///////////////////////////////////////////////////////////////////////////////
// CMemFile::GetStatus implementation
BOOL CMemFile::GetStatus(CFileStatus& rStatus) const
{
ASSERT_VALID(this);
rStatus.m_ctime = 0;
rStatus.m_mtime = 0;
rStatus.m_atime = 0;
rStatus.m_size = m_nFileSize;
rStatus.m_attribute = normal;
rStatus.m_szFullName[0] = '\0';
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////