Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfstream_win32io.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 00019 #include <fstream> 00020 00021 #if !defined (_STLP_WCE) 00022 # ifdef __BORLANDC__ 00023 # include <cfcntl.h> // For _O_RDONLY, etc 00024 # else 00025 # include <io.h> // For _get_osfhandle 00026 # include <fcntl.h> // For _O_RDONLY, etc 00027 # endif 00028 # include <sys/stat.h> // For _fstat 00029 #endif 00030 00031 #define _TEXTBUF_SIZE 0x1000 00032 00033 const _STLP_fd INVALID_STLP_FD = INVALID_HANDLE_VALUE; 00034 00035 #if !defined (INVALID_SET_FILE_POINTER) 00036 # define INVALID_SET_FILE_POINTER 0xffffffff 00037 #endif 00038 00039 #ifndef O_ACCMODE 00040 # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 00041 #endif 00042 00043 _STLP_BEGIN_NAMESPACE 00044 00045 #if !defined(__MSL__) && !defined(_STLP_WCE) 00046 static ios_base::openmode flag_to_openmode(int mode) { 00047 ios_base::openmode ret = ios_base::__default_mode; 00048 00049 switch (mode & O_ACCMODE) { 00050 case O_RDONLY: 00051 ret = ios_base::in; break; 00052 case O_WRONLY: 00053 ret = ios_base::out; break; 00054 case O_RDWR: 00055 ret = ios_base::in | ios_base::out; break; 00056 } 00057 00058 if (mode & O_APPEND) 00059 ret |= ios_base::app; 00060 00061 if (mode & O_BINARY) 00062 ret |= ios_base::binary; 00063 00064 return ret; 00065 } 00066 #endif 00067 00068 _STLP_MOVE_TO_PRIV_NAMESPACE 00069 00070 // Helper functions for _Filebuf_base. 00071 00072 static bool __is_regular_file(_STLP_fd fd) { 00073 BY_HANDLE_FILE_INFORMATION info; 00074 00075 // Return true if the file handle isn't a directory. 00076 return GetFileInformationByHandle(fd, &info) && 00077 ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0); 00078 } 00079 00080 // Number of characters in the file. 00081 static streamoff __file_size(_STLP_fd fd) { 00082 streamoff ret = 0; 00083 00084 LARGE_INTEGER li; 00085 li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart); 00086 if (li.LowPart != INVALID_FILE_SIZE || GetLastError() == NO_ERROR) 00087 ret = li.QuadPart; 00088 00089 return ret; 00090 } 00091 00092 _STLP_MOVE_TO_STD_NAMESPACE 00093 00094 // Visual C++ and Intel use this, but not Metrowerks 00095 // Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version 00096 #if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 00097 (defined (__MINGW32__) && defined (__MSVCRT__)) 00098 00099 // fcntl(fileno, F_GETFL) for Microsoft library 00100 // 'semi-documented' defines: 00101 # define IOINFO_L2E 5 00102 # define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) 00103 # define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \ 00104 ((i) & (IOINFO_ARRAY_ELTS - 1)) ) 00105 # define FAPPEND 0x20 // O_APPEND flag 00106 # define FTEXT 0x80 // O_TEXT flag 00107 // end of 'semi-documented' defines 00108 00109 // 'semi-documented' internal structure 00110 extern "C" { 00111 struct ioinfo { 00112 long osfhnd; // the real os HANDLE 00113 char osfile; // file handle flags 00114 char pipech; // pipe buffer 00115 # if defined (_MT) 00116 // multi-threaded locking 00117 int lockinitflag; 00118 CRITICAL_SECTION lock; 00119 # endif 00120 }; 00121 # if defined (__MINGW32__) 00122 __MINGW_IMPORT ioinfo * __pioinfo[]; 00123 # else 00124 extern _CRTIMP ioinfo * __pioinfo[]; 00125 # endif 00126 } // extern "C" 00127 // end of 'semi-documented' declarations 00128 00129 static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { 00130 char dosflags = 0; 00131 if (fd >= 0) 00132 dosflags = _pioinfo(fd)->osfile; 00133 //else 00134 //the file will be considered as open in binary mode with no append attribute 00135 // end of 'semi-documented' stuff 00136 00137 int mode = 0; 00138 if (dosflags & FAPPEND) 00139 mode |= O_APPEND; 00140 00141 if (dosflags & FTEXT) 00142 mode |= O_TEXT; 00143 else 00144 mode |= O_BINARY; 00145 00146 // For Read/Write access we have to guess 00147 DWORD dummy, dummy2; 00148 BOOL writeOk = WriteFile(oshandle, &dummy2, 0, &dummy, 0); 00149 BOOL readOk = ReadFile(oshandle, &dummy2, 0, &dummy, NULL); 00150 if (writeOk && readOk) 00151 mode |= O_RDWR; 00152 else if (readOk) 00153 mode |= O_RDONLY; 00154 else 00155 mode |= O_WRONLY; 00156 00157 return flag_to_openmode(mode); 00158 } 00159 00160 #elif defined (__DMC__) 00161 00162 # define FHND_APPEND 0x04 00163 # define FHND_DEVICE 0x08 00164 # define FHND_TEXT 0x10 00165 00166 extern "C" unsigned char __fhnd_info[_NFILE]; 00167 00168 static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { 00169 int mode = 0; 00170 00171 if (__fhnd_info[fd] & FHND_APPEND) 00172 mode |= O_APPEND; 00173 00174 if (__fhnd_info[fd] & FHND_TEXT == 0) 00175 mode |= O_BINARY; 00176 00177 for (FILE *fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) { 00178 if ((fileno(fp) == fd) && (fp->_flag & (_IOREAD | _IOWRT | _IORW))) { 00179 const int osflags = fp->_flag; 00180 00181 if ((osflags & _IOREAD) && !(osflags & _IOWRT) && !(osflags & _IORW)) 00182 mode |= O_RDONLY; 00183 else if ((osflags & _IOWRT) && !(osflags & _IOREAD) && !(osflags & _IORW)) 00184 mode |= O_WRONLY; 00185 else 00186 mode |= O_RDWR; 00187 break; 00188 } 00189 } 00190 00191 return flag_to_openmode(mode); 00192 } 00193 #endif 00194 00195 size_t _Filebuf_base::_M_page_size = 4096; 00196 00197 _Filebuf_base::_Filebuf_base() 00198 : _M_file_id(INVALID_STLP_FD), 00199 _M_openmode(0), 00200 _M_is_open(false), 00201 _M_should_close(false), 00202 _M_view_id(0) 00203 {} 00204 00205 void _Filebuf_base::_S_initialize() { 00206 SYSTEM_INFO SystemInfo; 00207 GetSystemInfo(&SystemInfo); 00208 _M_page_size = SystemInfo.dwPageSize; 00209 // might be .dwAllocationGranularity 00210 } 00211 00212 // Return the size of the file. This is a wrapper for stat. 00213 // Returns zero if the size cannot be determined or is ill-defined. 00214 streamoff _Filebuf_base::_M_file_size() { 00215 return _STLP_PRIV __file_size(_M_file_id); 00216 } 00217 00218 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, 00219 long permission) { 00220 _STLP_fd file_no; 00221 00222 if (_M_is_open) 00223 return false; 00224 00225 DWORD dwDesiredAccess, dwCreationDisposition; 00226 bool doTruncate = false; 00227 00228 switch (openmode & (~ios_base::ate & ~ios_base::binary)) { 00229 case ios_base::out: 00230 case ios_base::out | ios_base::trunc: 00231 dwDesiredAccess = GENERIC_WRITE; 00232 dwCreationDisposition = OPEN_ALWAYS; 00233 // boris : even though it is very non-intuitive, standard 00234 // requires them both to behave same. 00235 doTruncate = true; 00236 break; 00237 case ios_base::out | ios_base::app: 00238 dwDesiredAccess = GENERIC_WRITE; 00239 dwCreationDisposition = OPEN_ALWAYS; 00240 break; 00241 case ios_base::in: 00242 dwDesiredAccess = GENERIC_READ; 00243 dwCreationDisposition = OPEN_EXISTING; 00244 permission = 0; // Irrelevant unless we're writing. 00245 break; 00246 case ios_base::in | ios_base::out: 00247 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 00248 dwCreationDisposition = OPEN_EXISTING; 00249 break; 00250 case ios_base::in | ios_base::out | ios_base::trunc: 00251 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 00252 dwCreationDisposition = OPEN_ALWAYS; 00253 doTruncate = true; 00254 break; 00255 default: // The above are the only combinations of 00256 return false; // flags allowed by the C++ standard. 00257 } 00258 00259 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 00260 00261 #if defined(_STLP_USE_WIDE_INTERFACE) 00262 file_no = CreateFile (_STLP_PRIV __ASCIIToWide(name).c_str(), 00263 #else 00264 file_no = CreateFileA(name, 00265 #endif 00266 dwDesiredAccess, dwShareMode, 0, 00267 dwCreationDisposition, permission, 0); 00268 00269 if (file_no == INVALID_STLP_FD) 00270 return false; 00271 00272 if ( 00273 #if !defined (_STLP_WCE) 00274 GetFileType(file_no) == FILE_TYPE_DISK && 00275 #endif 00276 ((doTruncate && SetEndOfFile(file_no) == 0) || 00277 (((openmode & ios_base::ate) != 0) && 00278 (SetFilePointer(file_no, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)))) { 00279 CloseHandle(file_no); 00280 return false; 00281 } 00282 00283 _M_is_open = true; 00284 _M_file_id = file_no; 00285 _M_should_close = _M_is_open; 00286 _M_openmode = openmode; 00287 00288 if (_M_is_open) 00289 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 00290 00291 return (_M_is_open != 0); 00292 } 00293 00294 bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) { 00295 // This doesn't really grant everyone in the world read/write 00296 // access. On Unix, file-creation system calls always clear 00297 // bits that are set in the umask from the permissions flag. 00298 return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL); 00299 } 00300 00301 bool _Filebuf_base::_M_open(_STLP_fd __id, ios_base::openmode init_mode) { 00302 #if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 00303 (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__) 00304 00305 if (_M_is_open || __id == INVALID_STLP_FD) 00306 return false; 00307 00308 if (init_mode != ios_base::__default_mode) 00309 _M_openmode = init_mode; 00310 else 00311 _M_openmode = _get_osfflags(-1, __id); 00312 00313 _M_is_open = true; 00314 _M_file_id = __id; 00315 _M_should_close = false; 00316 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 00317 00318 return true; 00319 #else 00320 (void)__id; 00321 (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning 00322 00323 // not available for the API 00324 return false; 00325 00326 #endif 00327 } 00328 00329 // Associated the filebuf with a file descriptor pointing to an already- 00330 // open file. Mode is set to be consistent with the way that the file 00331 // was opened. 00332 bool _Filebuf_base::_M_open(int file_no, ios_base::openmode init_mode) { 00333 if (_M_is_open || file_no < 0) 00334 return false; 00335 00336 #if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 00337 (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__) 00338 00339 HANDLE oshandle = (HANDLE)_get_osfhandle(file_no); 00340 if (oshandle == INVALID_STLP_FD) 00341 return false; 00342 00343 if (init_mode != ios_base::__default_mode) 00344 _M_openmode = init_mode; 00345 else 00346 _M_openmode = _get_osfflags(file_no, oshandle); 00347 00348 _M_file_id = oshandle; 00349 _M_is_open = true; 00350 _M_should_close = false; 00351 _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 00352 return true; 00353 #else 00354 _STLP_MARK_PARAMETER_AS_UNUSED(&init_mode) 00355 // not available for the API 00356 return false; 00357 #endif 00358 } 00359 00360 bool _Filebuf_base::_M_close() { 00361 if (!_M_is_open) 00362 return false; 00363 00364 bool ok; 00365 00366 if (!_M_should_close) 00367 ok = true; 00368 else { 00369 if (_M_file_id != INVALID_STLP_FD) { 00370 ok = (CloseHandle(_M_file_id) != 0); 00371 } 00372 else { 00373 ok = false; 00374 } 00375 } 00376 00377 _M_is_open = _M_should_close = false; 00378 _M_openmode = 0; 00379 return ok; 00380 } 00381 00382 00383 #define _STLP_LF 10 00384 #define _STLP_CR 13 00385 #define _STLP_CTRLZ 26 00386 00387 // Read up to n characters into a buffer. Return value is number of 00388 // characters read. 00389 ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) { 00390 ptrdiff_t readen = 0; 00391 //Here cast to size_t is safe as n cannot be negative. 00392 size_t chunkSize = (min)(size_t(0xffffffff), __STATIC_CAST(size_t, n)); 00393 // The following, while validating that we are still able to extract chunkSize 00394 // charaters to the buffer, avoids extraction of too small chunk of datas 00395 // which would be counter performant. 00396 while (__STATIC_CAST(size_t, (n - readen)) >= chunkSize) { 00397 DWORD numberOfBytesRead; 00398 ReadFile(_M_file_id, buf + readen, __STATIC_CAST(DWORD, chunkSize), &numberOfBytesRead, 0); 00399 00400 if (numberOfBytesRead == 0) 00401 break; 00402 00403 if (!(_M_openmode & ios_base::binary)) { 00404 // translate CR-LFs to LFs in the buffer 00405 char *to = buf + readen; 00406 char *from = to; 00407 char *last = from + numberOfBytesRead - 1; 00408 for (; from <= last && *from != _STLP_CTRLZ; ++from) { 00409 if (*from != _STLP_CR) 00410 *to++ = *from; 00411 else { // found CR 00412 if (from < last) { // not at buffer end 00413 if (*(from + 1) != _STLP_LF) 00414 *to++ = _STLP_CR; 00415 } 00416 else { // last char is CR, peek for LF 00417 char peek = ' '; 00418 DWORD NumberOfBytesPeeked; 00419 ReadFile(_M_file_id, (LPVOID)&peek, 1, &NumberOfBytesPeeked, 0); 00420 if (NumberOfBytesPeeked != 0) { 00421 if (peek != _STLP_LF) { //not a <CR><LF> combination 00422 *to++ = _STLP_CR; 00423 if ((to < buf + n) && (peek != _STLP_CR)) 00424 //We have enough place to store peek and it is no a special 00425 //_STLP_CR character, we can store it. 00426 *to++ = peek; 00427 else 00428 SetFilePointer(_M_file_id, (LONG)-1, 0, FILE_CURRENT); 00429 } 00430 else { 00431 // A <CR><LF> combination, we keep the <LF>: 00432 *to++ = _STLP_LF; 00433 } 00434 } 00435 else { 00436 /* This case is tedious, we could 00437 * - put peek back in the file but this would then generate an infinite loop 00438 * - report an error as we don't know if in a future call to ReadFile we won't then 00439 * get a <LF>. Doing so would make all files with a <CR> last an invalid file 00440 * for STLport, a hard solution for STLport clients. 00441 * - store the <CR> in the returned buffer, the chosen solution, even if in this 00442 * case we could miss a <CR><LF> combination. 00443 */ 00444 *to++ = _STLP_CR; 00445 } 00446 } 00447 } // found CR 00448 } // for 00449 readen = to - buf; 00450 // seek back to TEXT end of file if hit CTRL-Z 00451 if (from <= last) { // terminated due to CTRLZ 00452 SetFilePointer(_M_file_id, -(LONG)((last + 1) - from), 0, FILE_CURRENT); 00453 break; 00454 } 00455 } 00456 else 00457 readen += numberOfBytesRead; 00458 } 00459 return readen; 00460 } 00461 00462 // Write n characters from a buffer. Return value: true if we managed 00463 // to write the entire buffer, false if we didn't. 00464 bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) { 00465 for (;;) { 00466 ptrdiff_t written; 00467 00468 //In the following implementation we are going to cast most of the ptrdiff_t 00469 //values in size_t to work with coherent unsigned values. Doing so make code 00470 //more simple especially in the min function call. 00471 00472 // In append mode, every write does an implicit seek to the end 00473 // of the file. 00474 if (_M_openmode & ios_base::app) 00475 _M_seek(0, ios_base::end); 00476 00477 if (_M_openmode & ios_base::binary) { 00478 // binary mode 00479 size_t bytes_to_write = (size_t)n; 00480 DWORD NumberOfBytesWritten; 00481 written = 0; 00482 for (; bytes_to_write != 0;) { 00483 WriteFile(_M_file_id, buf + written, 00484 __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), bytes_to_write)), 00485 &NumberOfBytesWritten, 0); 00486 if (NumberOfBytesWritten == 0) 00487 return false; 00488 bytes_to_write -= NumberOfBytesWritten; 00489 written += NumberOfBytesWritten; 00490 } 00491 } 00492 else { 00493 char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end 00494 char * nextblock = buf, * ptrtextbuf = textbuf; 00495 char * endtextbuf = textbuf + _TEXTBUF_SIZE; 00496 char * endblock = buf + n; 00497 ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE); 00498 char * nextlf; 00499 00500 while ( (nextblocksize > 0) && 00501 (nextlf = (char *)memchr(nextblock, _STLP_LF, nextblocksize)) != 0) { 00502 ptrdiff_t linelength = nextlf - nextblock; 00503 memcpy(ptrtextbuf, nextblock, linelength); 00504 ptrtextbuf += linelength; 00505 nextblock += (linelength + 1); 00506 * ptrtextbuf ++ = _STLP_CR; 00507 * ptrtextbuf ++ = _STLP_LF; 00508 nextblocksize = (min) (ptrdiff_t(endblock - nextblock), 00509 (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf))); 00510 } 00511 // write out what's left, > condition is here since for LF at the end , 00512 // endtextbuf may get < ptrtextbuf ... 00513 if (nextblocksize > 0) { 00514 memcpy(ptrtextbuf, nextblock, nextblocksize); 00515 ptrtextbuf += nextblocksize; 00516 nextblock += nextblocksize; 00517 } 00518 // now write out the translated buffer 00519 char * writetextbuf = textbuf; 00520 for (size_t NumberOfBytesToWrite = (size_t)(ptrtextbuf - textbuf); 00521 NumberOfBytesToWrite;) { 00522 DWORD NumberOfBytesWritten; 00523 WriteFile((HANDLE)_M_file_id, writetextbuf, 00524 __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), NumberOfBytesToWrite)), 00525 &NumberOfBytesWritten, 0); 00526 if (!NumberOfBytesWritten) // write shortfall 00527 return false; 00528 writetextbuf += NumberOfBytesWritten; 00529 NumberOfBytesToWrite -= NumberOfBytesWritten; 00530 } 00531 // count non-translated characters 00532 written = (nextblock - buf); 00533 } 00534 00535 if (n == written) 00536 return true; 00537 else if (written > 0 && written < n) { 00538 n -= written; 00539 buf += written; 00540 } 00541 else 00542 return false; 00543 } 00544 } 00545 00546 // Wrapper for lseek or the like. 00547 streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) { 00548 streamoff result = -1; 00549 int whence; 00550 00551 switch(dir) { 00552 case ios_base::beg: 00553 if (offset < 0 /* || offset > _M_file_size() */ ) 00554 return streamoff(-1); 00555 whence = FILE_BEGIN; 00556 break; 00557 case ios_base::cur: 00558 whence = FILE_CURRENT; 00559 break; 00560 case ios_base::end: 00561 if (/* offset > 0 || */ -offset > _M_file_size() ) 00562 return streamoff(-1); 00563 whence = FILE_END; 00564 break; 00565 default: 00566 return streamoff(-1); 00567 } 00568 00569 LARGE_INTEGER li; 00570 li.QuadPart = offset; 00571 li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence); 00572 if (li.LowPart != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR) 00573 result = li.QuadPart; 00574 00575 return result; 00576 } 00577 00578 00579 // Attempts to memory-map len bytes of the current file, starting 00580 // at position offset. Precondition: offset is a multiple of the 00581 // page size. Postcondition: return value is a null pointer if the 00582 // memory mapping failed. Otherwise the return value is a pointer to 00583 // the memory-mapped file and the file position is set to offset. 00584 void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) { 00585 void* base; 00586 _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 , 00587 PAGE_READONLY, 0 /* len >> 32 */ , 00588 0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size 00589 0); 00590 00591 if (_M_view_id) { 00592 #if 0 00593 /* 00594 printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n", 00595 _M_view_id, _M_file_id, GetLastError(), 00596 (int)cur_filesize, ULL(offset) & 0xffffffff, len); 00597 */ 00598 #endif 00599 LARGE_INTEGER li; 00600 li.QuadPart = offset; 00601 base = MapViewOfFile(_M_view_id, FILE_MAP_READ, li.HighPart, li.LowPart, 00602 #if !defined (__DMC__) 00603 __STATIC_CAST(SIZE_T, len)); 00604 #else 00605 __STATIC_CAST(DWORD, len)); 00606 #endif 00607 // check if mapping succeded and is usable 00608 if (base == 0 || _M_seek(offset + len, ios_base::beg) < 0) { 00609 this->_M_unmap(base, len); 00610 base = 0; 00611 } 00612 } else 00613 base = 0; 00614 00615 return base; 00616 } 00617 00618 void _Filebuf_base::_M_unmap(void* base, streamoff len) { 00619 // precondition : there is a valid mapping at the moment 00620 if (base != NULL) 00621 UnmapViewOfFile(base); 00622 // destroy view handle as well 00623 if (_M_view_id != NULL) 00624 CloseHandle(_M_view_id); 00625 _M_view_id = NULL; 00626 (void)len; //unused variable 00627 } 00628 00629 _STLP_END_NAMESPACE Generated on Sun May 27 2012 04:35:11 for ReactOS by
1.7.6.1
|