|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.