|
|
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.