Annotation of mstools/mfc/src/file.cpp, revision 1.1.1.3

1.1       root        1: // This is a part of the Microsoft Foundation Classes C++ library.
                      2: // Copyright (C) 1992 Microsoft Corporation
                      3: // All rights reserved.
                      4: //
                      5: // This source code is only intended as a supplement to the
                      6: // Microsoft Foundation Classes Reference and Microsoft
                      7: // QuickHelp documentation provided with the library.
                      8: // See these sources for detailed information regarding the
                      9: // Microsoft Foundation Classes product.
                     10: 
                     11: #ifdef _WINDOWS
                     12: #include "afxwin.h"
                     13: #else
                     14: #include "afx.h"
                     15: #endif
                     16: #pragma hdrstop
                     17: 
                     18: #include <errno.h>
                     19: #include <io.h>
                     20: #include <limits.h>
                     21: #include <malloc.h>
                     22: 
                     23: #ifdef _DOSWIN
                     24: #include <sys\types.h>
                     25: #include <sys\stat.h>
                     26: #endif
                     27: 
                     28: #include "dosio_.h"
                     29: 
                     30: #ifdef AFX_CORE_SEG
                     31: #pragma code_seg(AFX_CORE_SEG)
                     32: #endif
                     33: 
                     34: #ifdef _DEBUG
                     35: #undef THIS_FILE
                     36: static char BASED_CODE THIS_FILE[] = __FILE__;
                     37: #endif
                     38: 
                     39: #define new DEBUG_NEW
                     40: 
                     41: ////////////////////////////////////////////////////////////////////////////
                     42: 
                     43: #ifdef _DOSWIN
                     44: 
                     45: // DOS INT 21h functions not provided by C Runtimes
                     46: // additional Dos calls
                     47: #pragma optimize("qgel", off) // assembler cannot be globally optimized
                     48: 
                     49: UINT _Afx_seek(UINT hFile, LONG lOff, UINT nMode, DWORD FAR* lpdwNew)
                     50: { 
                     51:        UINT res;
                     52:        *lpdwNew = -1;
                     53:        _asm { 
                     54:                        mov     bx, hFile
                     55:                        mov     ax, nMode
                     56:                        mov     ah, 42h
                     57:                        mov     dx, word ptr lOff
                     58:                        mov     cx, word ptr lOff+2
                     59:                        DOSCALL
                     60:                        jc      __seek_err
                     61:                        les     bx, lpdwNew
                     62:                        mov     word ptr es:[bx], ax
                     63:                        mov     word ptr es:[bx+2], dx
                     64:                        xor     ax, ax
                     65:        __seek_err:
                     66:                        mov     res, ax
                     67:        }
                     68:        return res;
                     69: }
                     70:                
                     71: UINT _Afx_rename(LPCSTR lpszOld, LPCSTR lpszNew)
                     72: { 
                     73:        UINT res;
                     74:        _asm { 
                     75:                        mov     bx, ds
                     76:                        lds     dx, lpszOld
                     77:                        les     di, lpszNew
                     78:                        mov     ax, 5600h
                     79:                        DOSCALL
                     80:                        jc      __rename_err
                     81:                        xor     ax, ax
                     82:        __rename_err:
                     83:                        mov     res, ax
                     84:                        mov     ds, bx
                     85:        }
                     86:        return res;
                     87: }
                     88: 
                     89: UINT _Afx_remove(LPCSTR lpsz)  
                     90: { 
                     91:        UINT res;
                     92:        _asm { 
                     93:                        mov     bx, ds
                     94:                        lds     dx, lpsz
                     95:                        mov     ax, 4100h
                     96:                        DOSCALL
                     97:                        jc      __remove_err
                     98:                        xor     ax, ax
                     99:        __remove_err:
                    100:                        mov     res, ax
                    101:                        mov     ds, bx
                    102:        }
                    103:        return res;
                    104: }
                    105: 
                    106: UINT _Afx_lock(UINT hFile, DWORD dwStart, DWORD dwLen, BOOL bUnlock)
                    107: { 
                    108:        UINT res;
                    109:        _asm { 
                    110:                        mov     ax, bUnlock
                    111:                        mov     ah, 5ch
                    112:                        mov     bx, hFile
                    113:                        mov     dx, word ptr dwStart
                    114:                        mov     cx, word ptr dwStart+2
                    115:                        mov     di, word ptr dwLen
                    116:                        mov     si, word ptr dwLen+2
                    117:                        DOSCALL
                    118:                        jc      __lock_err1
                    119:                        xor     ax, ax
                    120:        __lock_err1:
                    121:                        mov     res, ax
                    122:                        
                    123:        }
                    124:        return res;
                    125: }
                    126: 
                    127: #pragma optimize("", on)    // return to default optimizations
                    128: 
                    129: #endif // _DOSWIN
                    130: 
                    131: /////////////////////////////////////////////////////////////////////////////
                    132: // CFileStatus implementation
                    133: #ifdef _DEBUG
                    134: void
                    135: CFileStatus::Dump(CDumpContext& dc) const
                    136: {           
                    137:        dc << "file status information:";
                    138:        dc << "\nm_ctime = " << m_ctime;
                    139:        dc << "\nm_mtime = " << m_mtime;
                    140:        dc << "\nm_atime = " << m_atime;
                    141:        dc << "\nm_size = " << m_size;
                    142:        dc << "\nm_attribute = " << m_attribute;
                    143:        dc << "\nm_szFullName = " << m_szFullName;
                    144: }
                    145: #endif
                    146: 
                    147: 
                    148: ////////////////////////////////////////////////////////////////////////////
                    149: // CFile implementation
                    150: IMPLEMENT_DYNAMIC(CFile, CObject)
                    151: 
                    152: 
                    153: CFile::CFile()
                    154: {
                    155:        m_hFile = hFileNull;
                    156:        m_bCloseOnDelete = FALSE;
                    157: }
                    158: 
                    159: CFile::CFile(int hFile)
                    160: {
                    161:        m_hFile = hFile;
                    162:        m_bCloseOnDelete = FALSE;
                    163: }
                    164: 
                    165: CFile::CFile(const char* pszFileName, UINT nOpenFlags)
                    166: {
                    167:        ASSERT(AfxIsValidAddress(pszFileName, strlen(pszFileName), FALSE));
                    168: 
                    169:        CFileException e;
                    170:        if (!this->Open(pszFileName, nOpenFlags, &e))
                    171:                AfxThrowFileException(e.m_cause, e.m_lOsError);
                    172: }
                    173: 
                    174: CFile::~CFile()
                    175: {   
                    176:        if (m_hFile != hFileNull && m_bCloseOnDelete)
                    177:                Close();
                    178: }
                    179: 
                    180: CFile*
                    181: CFile::Duplicate() const
                    182: {
                    183:        ASSERT_VALID(this);
                    184:        ASSERT(m_hFile != hFileNull);
                    185: 
                    186:        CFile* pFile = new CFile(hFileNull);
                    187: #ifdef _DOSWIN
                    188:        pFile->m_hFile = _dup(this->m_hFile);
                    189: #else
                    190:        if (!::DuplicateHandle(::GetCurrentProcess(),
                    191:                (HANDLE)m_hFile, ::GetCurrentProcess(), 
                    192:                (LPHANDLE)&pFile->m_hFile, 0L, TRUE, DUPLICATE_SAME_ACCESS))
                    193:        {
                    194:                delete pFile;
                    195:                CFileException::ThrowOsError(::GetLastError());
                    196:        }
                    197: #endif
                    198:        pFile->m_bCloseOnDelete = this->m_bCloseOnDelete;
                    199:        return pFile;
                    200: }
                    201: 
                    202: BOOL
                    203: CFile::Open(const char* pszFileName, UINT nOpenFlags, 
                    204:        CFileException* pException /* = NULL */)
                    205: {
                    206:        ASSERT(AfxIsValidAddress(pszFileName, strlen(pszFileName), FALSE));
                    207:        ASSERT(pException == NULL || AfxIsValidAddress(pException, sizeof(CFileException)));
                    208:        ASSERT((nOpenFlags & typeText) == 0);
                    209: 
                    210:        // CFile objects are always binary and _dos_open does not need flag
                    211:        nOpenFlags &= ~(UINT)CFile::typeBinary;
                    212: 
                    213:        m_bCloseOnDelete = FALSE;
                    214:        m_hFile = hFileNull;
                    215: 
                    216: 
                    217: #ifdef _DOSWIN
                    218:        ASSERT_VALID(this);
                    219: 
                    220:        char szOemPath[_MAX_PATH];
                    221:        UINT nErr;
                    222: 
                    223:        AnsiToOem(pszFileName, szOemPath);
                    224: 
                    225:        if (nOpenFlags & (UINT)CFile::modeCreate)
                    226:        {
                    227:                if ((nErr = _dos_creat(szOemPath, CFile::normal, (int*)&m_hFile)) != 0)
                    228:                {
                    229:                        if (pException != NULL)
                    230:                        {
                    231:                                pException->m_lOsError = nErr;
                    232:                                pException->m_cause = CFileException::OsErrorToException(nErr);
                    233:                                return FALSE; // file was not created
                    234:                        }
                    235:                }
                    236:                if ((nErr = _dos_close(m_hFile)) != 0)
                    237:                {
                    238:                        // try to delete the file and throw modeCreate exception
                    239:                        _Afx_remove(szOemPath);
                    240:                        if (pException != NULL)
                    241:                        {
                    242:                                pException->m_lOsError = nErr;
                    243:                                pException->m_cause = CFileException::OsErrorToException(nErr);
                    244:                        }
                    245:                        return FALSE;
                    246:                }
                    247:        }
                    248: 
                    249:        // the file has been modeCreated if needed, now open it
                    250:        if ((nErr = _dos_open(szOemPath, nOpenFlags & ~(UINT)CFile::modeCreate, (int*)&m_hFile)) != 0)
                    251:        {
                    252:                // try to delete the file and throw open exception
                    253:                if (pException != NULL)
                    254:                {
                    255:                        pException->m_lOsError = nErr;
                    256:                        pException->m_cause = CFileException::OsErrorToException(nErr);
                    257:                }
                    258:                return FALSE;
                    259:        }
                    260: #endif
                    261: 
                    262: #ifdef _NTWIN
                    263:        ASSERT_VALID(this);
                    264:        ASSERT(sizeof(HFILE) == sizeof(int));
                    265:        ASSERT(CFile::shareCompat == 0);
                    266: 
                    267:        OFSTRUCT of;
                    268: 
                    269:        if (((int)(m_hFile = (int)::OpenFile((LPSTR)pszFileName, &of, nOpenFlags))) < 0)
                    270:        {
                    271:                if (pException != NULL)
                    272:                {
                    273:                        pException->m_lOsError = of.nErrCode;
                    274:                        pException->m_cause = CFileException::OsErrorToException((LONG)of.nErrCode);
                    275:                }
                    276:                return FALSE;
                    277:        }
                    278: #endif
                    279: 
                    280:        m_bCloseOnDelete = TRUE;
                    281:        return TRUE;
                    282: }
                    283: 
                    284: 
                    285: UINT
                    286: CFile::Read(void FAR* lpBuf, UINT nCount)
                    287: {
                    288:        ASSERT_VALID(this);
                    289:        ASSERT(m_hFile != hFileNull);
                    290:        ASSERT(lpBuf != NULL);
                    291:        ASSERT(AfxIsValidAddress(lpBuf, nCount));
                    292: 
                    293:        UINT nRead = 0;
                    294:        UINT nErr;
                    295: 
                    296:        if ((nErr = _dos_read(m_hFile, lpBuf, nCount, &nRead)) != 0)
                    297:                CFileException::ThrowOsError(nErr);
                    298:                
                    299:        return nRead;
                    300: }
                    301: 
                    302: void
                    303: CFile::Write(const void FAR* lpBuf, UINT nCount)
                    304: {
                    305:        ASSERT_VALID(this);
                    306:        ASSERT(m_hFile != hFileNull);
                    307:        ASSERT(lpBuf != NULL);
                    308:        ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
                    309: 
                    310:        UINT nWritten = 0;
                    311:        UINT nErr;
                    312: 
                    313:        if ((nErr = _dos_write(m_hFile, lpBuf, nCount, &nWritten)) != 0)
                    314:                CFileException::ThrowOsError(nErr);
                    315:        
                    316:        if (nCount != nWritten)
                    317:                AfxThrowFileException(CFileException::diskFull);
                    318: }
                    319: 
                    320: 
                    321: LONG
                    322: CFile::Seek(LONG lOff, UINT nFrom)
                    323: {
                    324:        ASSERT_VALID(this);
                    325:        ASSERT(m_hFile != hFileNull);
                    326:        ASSERT(nFrom == CFile::begin || nFrom == CFile::end || nFrom == CFile::current);
                    327: 
                    328:        DWORD dwNew;
                    329:        UINT nErr;
                    330: 
                    331:        if ((nErr  = _Afx_seek(m_hFile, lOff, nFrom, &dwNew)) != 0)
                    332:                CFileException::ThrowOsError(nErr);
                    333:        
                    334:        return dwNew;
                    335: }
                    336: 
                    337: 
                    338: DWORD
                    339: CFile::GetPosition() const
                    340: {
                    341:        ASSERT_VALID(this);
                    342:        ASSERT(m_hFile != hFileNull);
                    343: 
                    344:        DWORD dwPos;
                    345:        UINT nErr;
                    346: 
                    347:        if ((nErr = _Afx_seek(m_hFile, 0, CFile::current, &dwPos)) != 0)
                    348:                CFileException::ThrowOsError(nErr);
                    349:        
                    350:        return dwPos;
                    351: }
                    352: 
                    353: 
                    354: #pragma optimize("qgel", off) // assembler cannot be globally optimized
                    355: void
                    356: CFile::Flush()
                    357: {
                    358:        ASSERT_VALID(this);
                    359:        ASSERT(m_hFile != hFileNull);
                    360:        
                    361:        UINT nErr;
                    362: 
1.1.1.2   root      363: #ifdef _DOSWIN
1.1       root      364:        // SmartDrive 4.0 workaround, carry flag incorrectly propogated
                    365:                _asm { CLC }
1.1.1.2   root      366: #endif
1.1       root      367: 
                    368:        if ((nErr = _dos_commit(m_hFile)) != 0)
                    369:                CFileException::ThrowOsError(nErr);
                    370: }
                    371: #pragma optimize("", on)    // return to default optimizations
                    372: 
                    373: void
                    374: CFile::Close()
                    375: {
                    376:        ASSERT_VALID(this);
                    377:        ASSERT(m_hFile != hFileNull);
                    378: 
                    379:        UINT nErr;
                    380: 
                    381:        if (m_hFile != hFileNull && (nErr = _dos_close(m_hFile)) != 0)
                    382:                CFileException::ThrowOsError(nErr);
                    383: 
                    384:        m_hFile = hFileNull;
                    385:        m_bCloseOnDelete = FALSE;
                    386: }
                    387: 
                    388: 
                    389: void
                    390: CFile::LockRange(DWORD dwPos, DWORD dwCount)
                    391: {
                    392:        ASSERT_VALID(this);
                    393:        ASSERT(m_hFile != hFileNull);
                    394: 
                    395:        UINT nErr;
                    396: 
                    397:        if ((nErr = _Afx_lock(m_hFile, dwPos, dwCount, FALSE)) != 0)
                    398:                CFileException::ThrowOsError(nErr);
                    399: }
                    400: 
                    401: 
                    402: void
                    403: CFile::UnlockRange(DWORD dwPos, DWORD dwCount)
                    404: {
                    405:        ASSERT_VALID(this);
                    406:        ASSERT(m_hFile != hFileNull);
                    407: 
                    408:        UINT nErr;
                    409: 
                    410:        if ((nErr = _Afx_lock(m_hFile, dwPos, dwCount, TRUE)) != 0)
                    411:                CFileException::ThrowOsError(nErr);
                    412: }
                    413: 
                    414: 
                    415: void
                    416: CFile::SetLength(DWORD dwNewLen)
                    417: {
                    418:        ASSERT_VALID(this);
                    419:        ASSERT(m_hFile != hFileNull);
                    420: 
                    421: #ifdef _DOSWIN
                    422:        UINT nErr;
                    423:        UINT nWritten = 0;
                    424: 
                    425:        this->Seek(dwNewLen, CFile::begin);
                    426: 
                    427:        if ((nErr = _dos_write(m_hFile, NULL, 0, &nWritten)) != 0)
                    428:                CFileException::ThrowOsError(nErr);
                    429: #endif
                    430: #ifdef _NTWIN
                    431:        this->Seek((LONG)dwNewLen, (UINT)CFile::begin);
                    432: 
                    433:        if (!::SetEndOfFile((HANDLE)m_hFile))
                    434:                CFileException::ThrowOsError((LONG)::GetLastError());
                    435: #endif
                    436: }
                    437: 
                    438: DWORD
                    439: CFile::GetLength() const
                    440: {
                    441:        ASSERT_VALID(this);
                    442: 
                    443:        DWORD dwLen, dwCur;
                    444:        
                    445:        // Seek is a non const operation 
                    446:        dwCur = ((CFile*)this)->Seek(0, CFile::current);
                    447:        dwLen = ((CFile*)this)->SeekToEnd();
                    448:        VERIFY(dwCur == (DWORD)(((CFile*)this)->Seek(dwCur, CFile::begin)));
                    449: 
                    450:        return dwLen;
                    451: }
                    452: 
                    453: BOOL
                    454: CFile::GetStatus(CFileStatus& rStatus) const
                    455: {
                    456:        ASSERT_VALID(this);
                    457:        ASSERT(m_hFile != hFileNull);
                    458: 
                    459:        //NOTE: cannot return name of file from handle
                    460:        rStatus.m_szFullName[0] = '\0';
                    461: 
                    462: 
                    463: #ifdef _DOSWIN
                    464:        struct _stat s;
                    465: 
                    466:        if (_fstat(m_hFile, &s) == 0)
                    467:        {
                    468:                rStatus.m_ctime = CTime(s.st_atime);
                    469:                rStatus.m_atime = rStatus.m_ctime;
                    470:                rStatus.m_mtime = rStatus.m_ctime;
                    471:                rStatus.m_size = s.st_size;
                    472:                rStatus.m_attribute = 0;    // dos won't give us this from
                    473:                                                                        // just a fd, need the path name
                    474:                return TRUE;
                    475:        }   
                    476:        return FALSE;
                    477: #endif
                    478: #ifdef _NTWIN
                    479:        _FILETIME ftCreate, ftAccess, ftModify;
                    480:        if (!::GetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify))
                    481:                return FALSE;
                    482: 
                    483:        if ((rStatus.m_size = ::GetFileSize((HANDLE)m_hFile, NULL)) == (DWORD)-1L)
                    484:                return FALSE;
                    485: 
                    486:        rStatus.m_attribute = 0;                // nt won't give us this from
                    487:                                                                        // just a fd, need the path name
                    488: 
                    489:        rStatus.m_ctime = CTime(ftCreate);
                    490:        rStatus.m_atime = CTime(ftAccess);
                    491:        rStatus.m_mtime = CTime(ftModify);
                    492: 
                    493:        if (rStatus.m_ctime.GetTime() == 0)
                    494:                rStatus.m_ctime = rStatus.m_mtime;
                    495: 
                    496:        if (rStatus.m_atime.GetTime() == 0)
                    497:                rStatus.m_atime = rStatus.m_mtime;
                    498: 
                    499:        return TRUE;
                    500: #endif
                    501: }
                    502: 
                    503: void
                    504: CFile::Rename(const char* pszOldName, const char* pszNewName)
                    505: {
                    506:        char szOld[_MAX_PATH];
                    507:        char szNew[_MAX_PATH];
                    508:        UINT nErr;
                    509: 
                    510:        AnsiToOem(pszOldName, szOld);
                    511:        AnsiToOem(pszNewName, szNew);
                    512: 
                    513:        if ((nErr = _Afx_rename(szOld, szNew)) != 0)
                    514:                CFileException::ThrowOsError(nErr);
                    515: 
                    516: }
                    517: 
                    518: void
                    519: CFile::Remove(const char* pszFileName)
                    520: {
                    521:        UINT nErr;
                    522:        char sz[_MAX_PATH];
                    523: 
                    524:        AnsiToOem(pszFileName, sz);
                    525: 
                    526:        if ((nErr = _Afx_remove(sz)) != 0)
                    527:                CFileException::ThrowOsError(nErr);
                    528: }
                    529: 
                    530: 
                    531: BOOL
                    532: CFile::GetStatus(const char* pszFileName, CFileStatus& rStatus)
                    533: {
                    534: 
                    535: #ifdef _DOSWIN
                    536:        char sz[_MAX_PATH];
                    537: 
                    538:        // first fill in the full name of the file, undefined if we return FALSE
                    539:        if (_fullpath(sz, pszFileName, _MAX_PATH) == NULL)
                    540:        {
                    541:                rStatus.m_szFullName[0] = '\0';
                    542:                return FALSE;
                    543:        }
                    544:        strncpy(rStatus.m_szFullName, sz, _MAX_PATH);
                    545: 
                    546:        // finish filling in the structure
                    547:        WORD wAttr = CFile::normal | CFile::readOnly |
                    548:                                CFile::hidden | CFile::system |
                    549:                                CFile::directory | CFile::archive;
                    550:        struct _find_t find;
                    551: 
                    552:        AnsiToOem(pszFileName, sz);
                    553: 
                    554:        if (_dos_findfirst(sz, wAttr, &find) == 0)
                    555:        {
                    556:                rStatus.m_mtime = CTime((WORD)find.wr_date, (WORD)find.wr_time);
                    557:                rStatus.m_ctime = rStatus.m_mtime;
                    558:                rStatus.m_atime = rStatus.m_mtime;
                    559: 
                    560:                rStatus.m_size = find.size;
                    561:                rStatus.m_attribute = find.attrib;
                    562:                return TRUE;
                    563:        }
                    564:        else
                    565:                return FALSE;
                    566: #endif // _DOSWIN
                    567: #ifdef _NTWIN
                    568:        WIN32_FIND_DATA findFileData;
                    569:        OFSTRUCT of;
                    570:        HANDLE hFound;
                    571: 
                    572:        if ((hFound = FindFirstFile((LPTSTR)pszFileName, &findFileData)) == (HANDLE)(-1))
                    573:                return FALSE;
1.1.1.3 ! root      574: 
        !           575:        VERIFY(FindClose(hFound));
1.1       root      576: 
                    577:        OpenFile((LPSTR)pszFileName, &of, OF_PARSE);
                    578: #ifdef _WINDOWS
                    579:        VERIFY(OemToCharBuff((LPSTR)of.szPathName, (LPTSTR)rStatus.m_szFullName,
                    580:                _MAX_PATH));
                    581: #else
                    582:        strncpy(rStatus.m_szFullName, (LPTSTR)of.szPathName,
                    583:                sizeof(rStatus.m_szFullName)-1);
                    584: #endif
                    585:        rStatus.m_szFullName[_MAX_PATH-1] = '\0';
                    586:        rStatus.m_attribute = (BYTE)(findFileData.dwFileAttributes & ~0x80);
                    587: 
                    588:        ASSERT(findFileData.nFileSizeHigh == 0);
                    589:        rStatus.m_size = (LONG) findFileData.nFileSizeLow;
                    590:        ASSERT(rStatus.m_size >= 0);
                    591: 
                    592:        rStatus.m_ctime = CTime(findFileData.ftCreationTime);
                    593:        rStatus.m_atime = CTime(findFileData.ftLastAccessTime);
                    594:        rStatus.m_mtime = CTime(findFileData.ftLastWriteTime);
                    595: 
                    596:        if (rStatus.m_ctime.GetTime() == 0)
                    597:                rStatus.m_ctime = rStatus.m_mtime;
                    598: 
                    599:        if (rStatus.m_atime.GetTime() == 0)
                    600:                rStatus.m_atime = rStatus.m_mtime;
                    601: 
                    602:        return TRUE;
                    603: #endif
                    604: }
                    605: 
1.1.1.2   root      606: #ifdef _NTWIN
1.1.1.3 ! root      607: // NOTE: Implementation helper function.
1.1.1.2   root      608: static void NEAR TimeToFileTime(const CTime& time, LPFILETIME pFileTime)
                    609: {
                    610:        _SYSTEMTIME sysTime;
                    611:        sysTime.wYear  = time.GetYear();
                    612:        sysTime.wMonth = time.GetMonth();
                    613:        sysTime.wDay   = time.GetDay();
                    614:        sysTime.wHour = time.GetHour();
                    615:        sysTime.wMinute = time.GetMinute();
                    616:        sysTime.wSecond = time.GetSecond();
                    617:        sysTime.wMilliseconds = 0;
                    618: 
                    619:        if (!SystemTimeToFileTime((LPSYSTEMTIME)&sysTime, pFileTime));
                    620:                CFileException::ThrowOsError((LONG)::GetLastError());
                    621: }
                    622: #endif
1.1       root      623: 
                    624: void
                    625: CFile::SetStatus(const char* pszFileName, const CFileStatus& status)
                    626: {
                    627: 
                    628: #ifdef _DOSWIN
                    629:        UINT nErr;
                    630:        UINT wAttr;
                    631:        char sz[_MAX_PATH];
                    632: 
                    633:        AnsiToOem(pszFileName, sz);
                    634: 
                    635:        if ((nErr = _dos_getfileattr(sz, &wAttr)) != 0)
                    636:                CFileException::ThrowOsError(nErr);
                    637: 
                    638:        if (status.m_attribute != wAttr && wAttr & CFile::readOnly)
                    639:        {
                    640:                // Set file attribute, only if currently readonly.
                    641:                // This way we will be able to modify the time assuming the
                    642:                // caller changed the file from readonly.
                    643:                if ((nErr = _dos_setfileattr(sz, status.m_attribute)) != 0)
                    644:                        CFileException::ThrowOsError(nErr);
                    645:        }
                    646: 
                    647:        if (status.m_mtime.GetTime() != 0)
                    648:        {
                    649:                WORD wDate, wTime;
                    650:                int handle;
                    651: 
                    652:                // set the file date/time
                    653:                if ((nErr = _dos_open(sz, CFile::modeReadWrite, &handle)) != 0)
                    654:                        CFileException::ThrowOsError(nErr);
                    655: 
                    656:                wDate = (WORD)(((UINT)status.m_mtime.GetYear() - 1980) << 9);
                    657:                wDate += (WORD)(((UINT)status.m_mtime.GetMonth()) << 5);
                    658:                wDate += (WORD)((UINT)status.m_mtime.GetDay());
                    659: 
                    660:                wTime = (WORD)((UINT)(status.m_mtime.GetHour()) << 11);
                    661:                wTime += (WORD)((UINT)status.m_mtime.GetMinute() << 5);
                    662:                wTime += (WORD)((UINT)status.m_mtime.GetSecond() >> 1);
                    663: 
                    664:                if ((nErr = _dos_setftime(handle, wDate, wTime)) != 0)
                    665:                        CFileException::ThrowOsError(nErr);
                    666: 
                    667:                if ((nErr = _dos_close(handle)) != 0)
                    668:                        CFileException::ThrowOsError(nErr);
                    669:        }
                    670: 
                    671:        if (status.m_attribute != wAttr && !(wAttr & CFile::readOnly))
                    672:        {
                    673:                // Set file attribute, only if currently not readonly.
                    674:                if ((nErr = _dos_setfileattr(sz, status.m_attribute)) != 0)
                    675:                        CFileException::ThrowOsError(nErr);
                    676:        }
                    677: 
                    678: #endif // _DOSWIN
                    679: #ifdef _NTWIN
                    680:        DWORD wAttr;
                    681:        _FILETIME creationTime;
                    682:        _FILETIME lastAccessTime;
                    683:        _FILETIME lastWriteTime;
1.1.1.2   root      684:        LPFILETIME lpCreationTime = NULL;
                    685:        LPFILETIME lpLastAccessTime = NULL;
                    686:        LPFILETIME lpLastWriteTime = NULL;
1.1       root      687: 
                    688:        if ((wAttr = GetFileAttributes((LPTSTR)pszFileName)) == (DWORD)-1L)
                    689:                CFileException::ThrowOsError((LONG)GetLastError());
                    690: 
1.1.1.2   root      691:        if ((DWORD)status.m_attribute != wAttr && (wAttr & CFile::readOnly))
1.1       root      692:        {
                    693:                // Set file attribute, only if currently readonly.
                    694:                // This way we will be able to modify the time assuming the
                    695:                // caller changed the file from readonly.
                    696: 
                    697:                if (!SetFileAttributes((LPTSTR)pszFileName, (DWORD)status.m_attribute))
                    698:                        CFileException::ThrowOsError((LONG)GetLastError());
                    699:        }
                    700: 
                    701:        // last modification time
                    702:        if (status.m_mtime.GetTime() != 0)
                    703:        {
1.1.1.2   root      704:                TimeToFileTime(status.m_mtime, &lastWriteTime);
                    705:                lpLastWriteTime = &lastWriteTime;
                    706: 
1.1       root      707:                // last access time
                    708:                if (status.m_atime.GetTime() != 0)
                    709:                {
1.1.1.2   root      710:                        TimeToFileTime(status.m_atime, &lastAccessTime);
                    711:                        lpLastAccessTime = &lastAccessTime;
1.1       root      712:                }
                    713:        
                    714:                // create time
                    715:                if (status.m_ctime.GetTime() != 0)
                    716:                {
1.1.1.2   root      717:                        TimeToFileTime(status.m_ctime, &creationTime);
                    718:                        lpCreationTime = &creationTime;
1.1       root      719:                }
                    720:        
                    721:                OFSTRUCT of;
                    722:                HFILE hFile = OpenFile((LPSTR)pszFileName, &of, OF_READWRITE);
1.1.1.2   root      723: 
1.1       root      724:                if (hFile == (HFILE)-1L)
                    725:                        CFileException::ThrowOsError((LONG)::GetLastError());
                    726:        
                    727:                if (!SetFileTime((HANDLE)hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime))
                    728:                        CFileException::ThrowOsError((LONG)::GetLastError());
                    729:        
                    730:                if (_lclose(hFile) == -1)
                    731:                        CFileException::ThrowOsError((LONG)::GetLastError());
                    732:        
                    733:        } // m_mtime != 0
                    734: 
                    735:        if ((DWORD)status.m_attribute != wAttr && !(wAttr & CFile::readOnly))
                    736:        {
                    737:                if (!SetFileAttributes((LPTSTR)pszFileName, (DWORD)status.m_attribute))
                    738:                        CFileException::ThrowOsError((LONG)GetLastError());
                    739:        }
                    740: #endif // _NTWIN
                    741: }
                    742: 
                    743: 
                    744: #ifdef _DEBUG
                    745: void
                    746: CFile::AssertValid() const
                    747: {
                    748:        CObject::AssertValid();
                    749:        // we permit the descriptor m_hFile to be any value for derived classes
                    750: }
                    751: 
                    752: void
                    753: CFile::Dump(CDumpContext& dc) const
                    754: {
                    755:        ASSERT_VALID(this);
                    756: 
                    757:        CObject::Dump(dc);
                    758:        dc << "a " << GetRuntimeClass()->m_pszClassName << " with handle " << m_hFile;
                    759: }
                    760: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.