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