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

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:                _Afx_remove(szOemPath);
                    254:                if (pException != NULL)
                    255:                {
                    256:                        pException->m_lOsError = nErr;
                    257:                        pException->m_cause = CFileException::OsErrorToException(nErr);
                    258:                }
                    259:                return FALSE;
                    260:        }
                    261: #endif
                    262: 
                    263: #ifdef _NTWIN
                    264:        ASSERT_VALID(this);
                    265:        ASSERT(sizeof(HFILE) == sizeof(int));
                    266:        ASSERT(CFile::shareCompat == 0);
                    267: 
                    268:        OFSTRUCT of;
                    269: 
                    270:        if (((int)(m_hFile = (int)::OpenFile((LPSTR)pszFileName, &of, nOpenFlags))) < 0)
                    271:        {
                    272:                if (pException != NULL)
                    273:                {
                    274:                        pException->m_lOsError = of.nErrCode;
                    275:                        pException->m_cause = CFileException::OsErrorToException((LONG)of.nErrCode);
                    276:                }
                    277:                return FALSE;
                    278:        }
                    279: #endif
                    280: 
                    281:        m_bCloseOnDelete = TRUE;
                    282:        return TRUE;
                    283: }
                    284: 
                    285: 
                    286: UINT
                    287: CFile::Read(void FAR* lpBuf, UINT nCount)
                    288: {
                    289:        ASSERT_VALID(this);
                    290:        ASSERT(m_hFile != hFileNull);
                    291:        ASSERT(lpBuf != NULL);
                    292:        ASSERT(AfxIsValidAddress(lpBuf, nCount));
                    293: 
                    294:        UINT nRead = 0;
                    295:        UINT nErr;
                    296: 
                    297:        if ((nErr = _dos_read(m_hFile, lpBuf, nCount, &nRead)) != 0)
                    298:                CFileException::ThrowOsError(nErr);
                    299:                
                    300:        return nRead;
                    301: }
                    302: 
                    303: void
                    304: CFile::Write(const void FAR* lpBuf, UINT nCount)
                    305: {
                    306:        ASSERT_VALID(this);
                    307:        ASSERT(m_hFile != hFileNull);
                    308:        ASSERT(lpBuf != NULL);
                    309:        ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
                    310: 
                    311:        UINT nWritten = 0;
                    312:        UINT nErr;
                    313: 
                    314:        if ((nErr = _dos_write(m_hFile, lpBuf, nCount, &nWritten)) != 0)
                    315:                CFileException::ThrowOsError(nErr);
                    316:        
                    317:        if (nCount != nWritten)
                    318:                AfxThrowFileException(CFileException::diskFull);
                    319: }
                    320: 
                    321: 
                    322: LONG
                    323: CFile::Seek(LONG lOff, UINT nFrom)
                    324: {
                    325:        ASSERT_VALID(this);
                    326:        ASSERT(m_hFile != hFileNull);
                    327:        ASSERT(nFrom == CFile::begin || nFrom == CFile::end || nFrom == CFile::current);
                    328: 
                    329:        DWORD dwNew;
                    330:        UINT nErr;
                    331: 
                    332:        if ((nErr  = _Afx_seek(m_hFile, lOff, nFrom, &dwNew)) != 0)
                    333:                CFileException::ThrowOsError(nErr);
                    334:        
                    335:        return dwNew;
                    336: }
                    337: 
                    338: 
                    339: DWORD
                    340: CFile::GetPosition() const
                    341: {
                    342:        ASSERT_VALID(this);
                    343:        ASSERT(m_hFile != hFileNull);
                    344: 
                    345:        DWORD dwPos;
                    346:        UINT nErr;
                    347: 
                    348:        if ((nErr = _Afx_seek(m_hFile, 0, CFile::current, &dwPos)) != 0)
                    349:                CFileException::ThrowOsError(nErr);
                    350:        
                    351:        return dwPos;
                    352: }
                    353: 
                    354: 
                    355: #pragma optimize("qgel", off) // assembler cannot be globally optimized
                    356: void
                    357: CFile::Flush()
                    358: {
                    359:        ASSERT_VALID(this);
                    360:        ASSERT(m_hFile != hFileNull);
                    361:        
                    362:        UINT nErr;
                    363: 
                    364:        // SmartDrive 4.0 workaround, carry flag incorrectly propogated
                    365:                _asm { CLC }
                    366: 
                    367:        if ((nErr = _dos_commit(m_hFile)) != 0)
                    368:                CFileException::ThrowOsError(nErr);
                    369: }
                    370: #pragma optimize("", on)    // return to default optimizations
                    371: 
                    372: void
                    373: CFile::Close()
                    374: {
                    375:        ASSERT_VALID(this);
                    376:        ASSERT(m_hFile != hFileNull);
                    377: 
                    378:        UINT nErr;
                    379: 
                    380:        if (m_hFile != hFileNull && (nErr = _dos_close(m_hFile)) != 0)
                    381:                CFileException::ThrowOsError(nErr);
                    382: 
                    383:        m_hFile = hFileNull;
                    384:        m_bCloseOnDelete = FALSE;
                    385: }
                    386: 
                    387: 
                    388: void
                    389: CFile::LockRange(DWORD dwPos, DWORD dwCount)
                    390: {
                    391:        ASSERT_VALID(this);
                    392:        ASSERT(m_hFile != hFileNull);
                    393: 
                    394:        UINT nErr;
                    395: 
                    396:        if ((nErr = _Afx_lock(m_hFile, dwPos, dwCount, FALSE)) != 0)
                    397:                CFileException::ThrowOsError(nErr);
                    398: }
                    399: 
                    400: 
                    401: void
                    402: CFile::UnlockRange(DWORD dwPos, DWORD dwCount)
                    403: {
                    404:        ASSERT_VALID(this);
                    405:        ASSERT(m_hFile != hFileNull);
                    406: 
                    407:        UINT nErr;
                    408: 
                    409:        if ((nErr = _Afx_lock(m_hFile, dwPos, dwCount, TRUE)) != 0)
                    410:                CFileException::ThrowOsError(nErr);
                    411: }
                    412: 
                    413: 
                    414: void
                    415: CFile::SetLength(DWORD dwNewLen)
                    416: {
                    417:        ASSERT_VALID(this);
                    418:        ASSERT(m_hFile != hFileNull);
                    419: 
                    420: #ifdef _DOSWIN
                    421:        UINT nErr;
                    422:        UINT nWritten = 0;
                    423: 
                    424:        this->Seek(dwNewLen, CFile::begin);
                    425: 
                    426:        if ((nErr = _dos_write(m_hFile, NULL, 0, &nWritten)) != 0)
                    427:                CFileException::ThrowOsError(nErr);
                    428: #endif
                    429: #ifdef _NTWIN
                    430:        this->Seek((LONG)dwNewLen, (UINT)CFile::begin);
                    431: 
                    432:        if (!::SetEndOfFile((HANDLE)m_hFile))
                    433:                CFileException::ThrowOsError((LONG)::GetLastError());
                    434: #endif
                    435: }
                    436: 
                    437: DWORD
                    438: CFile::GetLength() const
                    439: {
                    440:        ASSERT_VALID(this);
                    441: 
                    442:        DWORD dwLen, dwCur;
                    443:        
                    444:        // Seek is a non const operation 
                    445:        dwCur = ((CFile*)this)->Seek(0, CFile::current);
                    446:        dwLen = ((CFile*)this)->SeekToEnd();
                    447:        VERIFY(dwCur == (DWORD)(((CFile*)this)->Seek(dwCur, CFile::begin)));
                    448: 
                    449:        return dwLen;
                    450: }
                    451: 
                    452: BOOL
                    453: CFile::GetStatus(CFileStatus& rStatus) const
                    454: {
                    455:        ASSERT_VALID(this);
                    456:        ASSERT(m_hFile != hFileNull);
                    457: 
                    458:        //NOTE: cannot return name of file from handle
                    459:        rStatus.m_szFullName[0] = '\0';
                    460: 
                    461: 
                    462: #ifdef _DOSWIN
                    463:        struct _stat s;
                    464: 
                    465:        if (_fstat(m_hFile, &s) == 0)
                    466:        {
                    467:                rStatus.m_ctime = CTime(s.st_atime);
                    468:                rStatus.m_atime = rStatus.m_ctime;
                    469:                rStatus.m_mtime = rStatus.m_ctime;
                    470:                rStatus.m_size = s.st_size;
                    471:                rStatus.m_attribute = 0;    // dos won't give us this from
                    472:                                                                        // just a fd, need the path name
                    473:                return TRUE;
                    474:        }   
                    475:        return FALSE;
                    476: #endif
                    477: #ifdef _NTWIN
                    478:        _FILETIME ftCreate, ftAccess, ftModify;
                    479:        if (!::GetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify))
                    480:                return FALSE;
                    481: 
                    482:        if ((rStatus.m_size = ::GetFileSize((HANDLE)m_hFile, NULL)) == (DWORD)-1L)
                    483:                return FALSE;
                    484: 
                    485:        rStatus.m_attribute = 0;                // nt won't give us this from
                    486:                                                                        // just a fd, need the path name
                    487: 
                    488:        rStatus.m_ctime = CTime(ftCreate);
                    489:        rStatus.m_atime = CTime(ftAccess);
                    490:        rStatus.m_mtime = CTime(ftModify);
                    491: 
                    492:        if (rStatus.m_ctime.GetTime() == 0)
                    493:                rStatus.m_ctime = rStatus.m_mtime;
                    494: 
                    495:        if (rStatus.m_atime.GetTime() == 0)
                    496:                rStatus.m_atime = rStatus.m_mtime;
                    497: 
                    498:        return TRUE;
                    499: #endif
                    500: }
                    501: 
                    502: void
                    503: CFile::Rename(const char* pszOldName, const char* pszNewName)
                    504: {
                    505:        char szOld[_MAX_PATH];
                    506:        char szNew[_MAX_PATH];
                    507:        UINT nErr;
                    508: 
                    509:        AnsiToOem(pszOldName, szOld);
                    510:        AnsiToOem(pszNewName, szNew);
                    511: 
                    512:        if ((nErr = _Afx_rename(szOld, szNew)) != 0)
                    513:                CFileException::ThrowOsError(nErr);
                    514: 
                    515: }
                    516: 
                    517: void
                    518: CFile::Remove(const char* pszFileName)
                    519: {
                    520:        UINT nErr;
                    521:        char sz[_MAX_PATH];
                    522: 
                    523:        AnsiToOem(pszFileName, sz);
                    524: 
                    525:        if ((nErr = _Afx_remove(sz)) != 0)
                    526:                CFileException::ThrowOsError(nErr);
                    527: }
                    528: 
                    529: 
                    530: BOOL
                    531: CFile::GetStatus(const char* pszFileName, CFileStatus& rStatus)
                    532: {
                    533: 
                    534: #ifdef _DOSWIN
                    535:        char sz[_MAX_PATH];
                    536: 
                    537:        // first fill in the full name of the file, undefined if we return FALSE
                    538:        if (_fullpath(sz, pszFileName, _MAX_PATH) == NULL)
                    539:        {
                    540:                rStatus.m_szFullName[0] = '\0';
                    541:                return FALSE;
                    542:        }
                    543:        strncpy(rStatus.m_szFullName, sz, _MAX_PATH);
                    544: 
                    545:        // finish filling in the structure
                    546:        WORD wAttr = CFile::normal | CFile::readOnly |
                    547:                                CFile::hidden | CFile::system |
                    548:                                CFile::directory | CFile::archive;
                    549:        struct _find_t find;
                    550: 
                    551:        AnsiToOem(pszFileName, sz);
                    552: 
                    553:        if (_dos_findfirst(sz, wAttr, &find) == 0)
                    554:        {
                    555:                rStatus.m_mtime = CTime((WORD)find.wr_date, (WORD)find.wr_time);
                    556:                rStatus.m_ctime = rStatus.m_mtime;
                    557:                rStatus.m_atime = rStatus.m_mtime;
                    558: 
                    559:                rStatus.m_size = find.size;
                    560:                rStatus.m_attribute = find.attrib;
                    561:                return TRUE;
                    562:        }
                    563:        else
                    564:                return FALSE;
                    565: #endif // _DOSWIN
                    566: #ifdef _NTWIN
                    567:        WIN32_FIND_DATA findFileData;
                    568:        OFSTRUCT of;
                    569:        HANDLE hFound;
                    570: 
                    571:        if ((hFound = FindFirstFile((LPTSTR)pszFileName, &findFileData)) == (HANDLE)(-1))
                    572:        {
                    573:                return FALSE;
                    574:        }
                    575:        else 
                    576:        {
                    577:                VERIFY(FindClose(hFound));
                    578:        }
                    579: 
                    580:        OpenFile((LPSTR)pszFileName, &of, OF_PARSE);
                    581: #ifdef _WINDOWS
                    582:        VERIFY(OemToCharBuff((LPSTR)of.szPathName, (LPTSTR)rStatus.m_szFullName,
                    583:                _MAX_PATH));
                    584: #else
                    585:        strncpy(rStatus.m_szFullName, (LPTSTR)of.szPathName,
                    586:                sizeof(rStatus.m_szFullName)-1);
                    587: #endif
                    588:        rStatus.m_szFullName[_MAX_PATH-1] = '\0';
                    589:        rStatus.m_attribute = (BYTE)(findFileData.dwFileAttributes & ~0x80);
                    590: 
                    591:        ASSERT(findFileData.nFileSizeHigh == 0);
                    592:        rStatus.m_size = (LONG) findFileData.nFileSizeLow;
                    593:        ASSERT(rStatus.m_size >= 0);
                    594: 
                    595:        rStatus.m_ctime = CTime(findFileData.ftCreationTime);
                    596:        rStatus.m_atime = CTime(findFileData.ftLastAccessTime);
                    597:        rStatus.m_mtime = CTime(findFileData.ftLastWriteTime);
                    598: 
                    599:        if (rStatus.m_ctime.GetTime() == 0)
                    600:                rStatus.m_ctime = rStatus.m_mtime;
                    601: 
                    602:        if (rStatus.m_atime.GetTime() == 0)
                    603:                rStatus.m_atime = rStatus.m_mtime;
                    604: 
                    605:        return TRUE;
                    606: #endif
                    607: }
                    608: 
                    609: 
                    610: void
                    611: CFile::SetStatus(const char* pszFileName, const CFileStatus& status)
                    612: {
                    613: 
                    614: #ifdef _DOSWIN
                    615:        UINT nErr;
                    616:        UINT wAttr;
                    617:        char sz[_MAX_PATH];
                    618: 
                    619:        AnsiToOem(pszFileName, sz);
                    620: 
                    621:        if ((nErr = _dos_getfileattr(sz, &wAttr)) != 0)
                    622:                CFileException::ThrowOsError(nErr);
                    623: 
                    624:        if (status.m_attribute != wAttr && wAttr & CFile::readOnly)
                    625:        {
                    626:                // Set file attribute, only if currently readonly.
                    627:                // This way we will be able to modify the time assuming the
                    628:                // caller changed the file from readonly.
                    629:                if ((nErr = _dos_setfileattr(sz, status.m_attribute)) != 0)
                    630:                        CFileException::ThrowOsError(nErr);
                    631:        }
                    632: 
                    633:        if (status.m_mtime.GetTime() != 0)
                    634:        {
                    635:                WORD wDate, wTime;
                    636:                int handle;
                    637: 
                    638:                // set the file date/time
                    639:                if ((nErr = _dos_open(sz, CFile::modeReadWrite, &handle)) != 0)
                    640:                        CFileException::ThrowOsError(nErr);
                    641: 
                    642:                wDate = (WORD)(((UINT)status.m_mtime.GetYear() - 1980) << 9);
                    643:                wDate += (WORD)(((UINT)status.m_mtime.GetMonth()) << 5);
                    644:                wDate += (WORD)((UINT)status.m_mtime.GetDay());
                    645: 
                    646:                wTime = (WORD)((UINT)(status.m_mtime.GetHour()) << 11);
                    647:                wTime += (WORD)((UINT)status.m_mtime.GetMinute() << 5);
                    648:                wTime += (WORD)((UINT)status.m_mtime.GetSecond() >> 1);
                    649: 
                    650:                if ((nErr = _dos_setftime(handle, wDate, wTime)) != 0)
                    651:                        CFileException::ThrowOsError(nErr);
                    652: 
                    653:                if ((nErr = _dos_close(handle)) != 0)
                    654:                        CFileException::ThrowOsError(nErr);
                    655:        }
                    656: 
                    657:        if (status.m_attribute != wAttr && !(wAttr & CFile::readOnly))
                    658:        {
                    659:                // Set file attribute, only if currently not readonly.
                    660:                if ((nErr = _dos_setfileattr(sz, status.m_attribute)) != 0)
                    661:                        CFileException::ThrowOsError(nErr);
                    662:        }
                    663: 
                    664: #endif // _DOSWIN
                    665: #ifdef _NTWIN
                    666:        // REVIEW LATER: JIMAD -- too much cookie cutter code!
                    667:        DWORD wAttr;
                    668:        _SYSTEMTIME sysTime;
                    669:        _FILETIME creationTime;
                    670:        _FILETIME lastAccessTime;
                    671:        _FILETIME lastWriteTime;
                    672:        LPFILETIME lpCreationTime;
                    673:        LPFILETIME lpLastAccessTime;
                    674:        LPFILETIME lpLastWriteTime;
                    675: 
                    676:        if ((wAttr = GetFileAttributes((LPTSTR)pszFileName)) == (DWORD)-1L)
                    677:                CFileException::ThrowOsError((LONG)GetLastError());
                    678: 
                    679:        if ((DWORD)status.m_attribute != wAttr && wAttr & CFile::readOnly)
                    680:        {
                    681:                // Set file attribute, only if currently readonly.
                    682:                // This way we will be able to modify the time assuming the
                    683:                // caller changed the file from readonly.
                    684: 
                    685:                if (!SetFileAttributes((LPTSTR)pszFileName, (DWORD)status.m_attribute))
                    686:                        CFileException::ThrowOsError((LONG)GetLastError());
                    687:        }
                    688: 
                    689:        // last modification time
                    690:        if (status.m_mtime.GetTime() != 0)
                    691:        {
                    692:                // if (status.m_mtime.GetTime() != 0)
                    693:                {                                                                               
                    694:                        sysTime.wYear  = status.m_mtime.GetYear();
                    695:                        sysTime.wMonth = status.m_mtime.GetMonth();
                    696:                        sysTime.wDay   = status.m_mtime.GetDay();
                    697:                        sysTime.wHour = status.m_mtime.GetHour();
                    698:                        sysTime.wMinute = status.m_mtime.GetMinute();
                    699:                        sysTime.wSecond = status.m_mtime.GetSecond();
                    700:                        sysTime.wMilliseconds = 0;
                    701:                        lpLastWriteTime = &lastWriteTime;
                    702:        
                    703:                        if (!SystemTimeToFileTime((LPSYSTEMTIME)&sysTime, lpLastWriteTime));
                    704:                                CFileException::ThrowOsError((LONG)::GetLastError());
                    705:                }
                    706:        
                    707:                // last access time
                    708:                if (status.m_atime.GetTime() != 0)
                    709:                {                                                                               
                    710:                        sysTime.wYear  = status.m_atime.GetYear();
                    711:                        sysTime.wMonth = status.m_atime.GetMonth();
                    712:                        sysTime.wDay   = status.m_atime.GetDay();
                    713:                        sysTime.wHour = status.m_atime.GetHour();
                    714:                        sysTime.wMinute = status.m_atime.GetMinute();
                    715:                        sysTime.wSecond = status.m_atime.GetSecond();
                    716:                        sysTime.wMilliseconds = 0;
                    717:                        lpLastAccessTime = &lastAccessTime;
                    718:        
                    719:                        if (!SystemTimeToFileTime((LPSYSTEMTIME)&sysTime, lpLastAccessTime));
                    720:                                CFileException::ThrowOsError((LONG)::GetLastError());
                    721:                }
                    722:                else
                    723:                {
                    724:                        lpLastAccessTime = NULL;
                    725:                }
                    726:        
                    727:                // create time
                    728:                if (status.m_ctime.GetTime() != 0)
                    729:                {                                                                               
                    730:                        sysTime.wYear  = status.m_ctime.GetYear();
                    731:                        sysTime.wMonth = status.m_ctime.GetMonth();
                    732:                        sysTime.wDay   = status.m_ctime.GetDay();
                    733:                        sysTime.wHour = status.m_ctime.GetHour();
                    734:                        sysTime.wMinute = status.m_ctime.GetMinute();
                    735:                        sysTime.wSecond = status.m_ctime.GetSecond();
                    736:                        sysTime.wMilliseconds = 0;
                    737:                        lpCreationTime = &creationTime;
                    738:        
                    739:                        if (!SystemTimeToFileTime((LPSYSTEMTIME)&sysTime, lpCreationTime))
                    740:                                CFileException::ThrowOsError((LONG)::GetLastError());
                    741:                }
                    742:                else
                    743:                {
                    744:                        lpCreationTime = NULL;
                    745:                }
                    746:        
                    747:                OFSTRUCT of;
                    748:                HFILE hFile = OpenFile((LPSTR)pszFileName, &of, OF_READWRITE);
                    749:        
                    750:                if (hFile == (HFILE)-1L)
                    751:                        CFileException::ThrowOsError((LONG)::GetLastError());
                    752:        
                    753:                if (!SetFileTime((HANDLE)hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime))
                    754:                        CFileException::ThrowOsError((LONG)::GetLastError());
                    755:        
                    756:                if (_lclose(hFile) == -1)
                    757:                        CFileException::ThrowOsError((LONG)::GetLastError());
                    758:        
                    759:        } // m_mtime != 0
                    760: 
                    761:        if ((DWORD)status.m_attribute != wAttr && !(wAttr & CFile::readOnly))
                    762:        {
                    763:                if (!SetFileAttributes((LPTSTR)pszFileName, (DWORD)status.m_attribute))
                    764:                        CFileException::ThrowOsError((LONG)GetLastError());
                    765:        }
                    766: #endif // _NTWIN
                    767: }
                    768: 
                    769: 
                    770: #ifdef _DEBUG
                    771: void
                    772: CFile::AssertValid() const
                    773: {
                    774:        CObject::AssertValid();
                    775:        // we permit the descriptor m_hFile to be any value for derived classes
                    776: }
                    777: 
                    778: void
                    779: CFile::Dump(CDumpContext& dc) const
                    780: {
                    781:        ASSERT_VALID(this);
                    782: 
                    783:        CObject::Dump(dc);
                    784:        dc << "a " << GetRuntimeClass()->m_pszClassName << " with handle " << m_hFile;
                    785: }
                    786: #endif

unix.superglobalmegacorp.com

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