ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

winfs.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2003, 2004, 2005 Martin Fuchs
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017  */
00018 
00019 
00020  //
00021  // Explorer clone
00022  //
00023  // winfs.cpp
00024  //
00025  // Martin Fuchs, 23.07.2003
00026  //
00027 
00028 
00029 #include <precomp.h>
00030 
00031 #ifndef _NO_WIN_FS
00032 
00033 //#include "winfs.h"
00034 
00035 
00036 int ScanNTFSStreams(Entry* entry, HANDLE hFile)
00037 {
00038     PVOID ctx = 0;
00039     DWORD read, seek_high;
00040     Entry** pnext = &entry->_down;
00041     int cnt = 0;
00042 
00043     for(;;) {
00044         struct NTFS_StreamHdr : public WIN32_STREAM_ID {
00045             WCHAR name_padding[_MAX_FNAME]; // room for reading stream name
00046         } hdr;
00047 
00048         if (!BackupRead(hFile, (LPBYTE)&hdr, (LPBYTE)&hdr.cStreamName-(LPBYTE)&hdr, &read, FALSE, FALSE, &ctx) ||
00049             (long)read!=(LPBYTE)&hdr.cStreamName-(LPBYTE)&hdr)
00050             break;
00051 
00052         if (hdr.dwStreamId == BACKUP_ALTERNATE_DATA) {
00053             if (hdr.dwStreamNameSize &&
00054                 BackupRead(hFile, (LPBYTE)hdr.cStreamName, hdr.dwStreamNameSize, &read, FALSE, FALSE, &ctx) &&
00055                 read==hdr.dwStreamNameSize)
00056             {
00057                 ++cnt;
00058 
00059                 int l = hdr.dwStreamNameSize / sizeof(WCHAR);
00060                 LPCWSTR p = hdr.cStreamName;
00061                 LPCWSTR e = hdr.cStreamName + l;
00062 
00063                 if (l>0 && *p==':') {
00064                     ++p, --l;
00065 
00066                     e = p;
00067 
00068                     while(l>0 && *e!=':')
00069                         ++e, --l;
00070 
00071                     l = e - p;
00072                 }
00073 
00074                 Entry* stream_entry = new WinEntry(entry);
00075 
00076                 memcpy(&stream_entry->_data, &entry->_data, sizeof(WIN32_FIND_DATA));
00077                 lstrcpy(stream_entry->_data.cFileName, String(p, l));
00078 
00079                 stream_entry->_down = NULL;
00080                 stream_entry->_expanded = false;
00081                 stream_entry->_scanned = false;
00082                 stream_entry->_level = entry->_level + 1;
00083 
00084                 *pnext = stream_entry;
00085                 pnext = &stream_entry->_next;
00086             }
00087         }
00088 
00089          // jump to the next stream header
00090         if (!BackupSeek(hFile, ~0, ~0, &read, &seek_high, &ctx)) {
00091             DWORD error = GetLastError();
00092 
00093             if (error != ERROR_SEEK) {
00094                 BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx);  // terminate BackupRead() loop
00095                 THROW_EXCEPTION(error);
00096                 //break;
00097             }
00098 
00099             hdr.Size.QuadPart -= read;
00100             hdr.Size.HighPart -= seek_high;
00101 
00102             BYTE buffer[4096];
00103 
00104             while(hdr.Size.QuadPart > 0) {
00105                 if (!BackupRead(hFile, buffer, sizeof(buffer), &read, FALSE, FALSE, &ctx) || read!=sizeof(buffer))
00106                     break;
00107 
00108                 hdr.Size.QuadPart -= read;
00109             }
00110         }
00111     }
00112 
00113     if (ctx)
00114         if (!BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx)) // terminate BackupRead() loop
00115             THROW_EXCEPTION(GetLastError());
00116 
00117     return cnt;
00118 }
00119 
00120 
00121 void WinDirectory::read_directory(int scan_flags)
00122 {
00123     CONTEXT("WinDirectory::read_directory()");
00124 
00125     int level = _level + 1;
00126 
00127     Entry* first_entry = NULL;
00128     Entry* last = NULL;
00129     Entry* entry;
00130 
00131     LPCTSTR path = (LPCTSTR)_path;
00132     TCHAR buffer[MAX_PATH], *pname;
00133     for(pname=buffer; *path; )
00134         *pname++ = *path++;
00135 
00136     lstrcpy(pname, TEXT("\\*"));
00137 
00138     WIN32_FIND_DATA w32fd;
00139     HANDLE hFind = FindFirstFile(buffer, &w32fd);
00140 
00141     if (hFind != INVALID_HANDLE_VALUE) {
00142         do {
00143             lstrcpy(pname+1, w32fd.cFileName);
00144 
00145             if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00146                 entry = new WinDirectory(this, buffer);
00147             else
00148                 entry = new WinEntry(this);
00149 
00150             if (!first_entry)
00151                 first_entry = entry;
00152 
00153             if (last)
00154                 last->_next = entry;
00155 
00156             memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
00157             entry->_level = level;
00158 
00159              // display file type names, but don't hide file extensions
00160             g_Globals._ftype_mgr.set_type(entry, true);
00161 
00162             if (!(scan_flags & SCAN_DONT_ACCESS)) {
00163                 HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
00164                                             0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
00165 
00166                 if (hFile != INVALID_HANDLE_VALUE) {
00167                     if (GetFileInformationByHandle(hFile, &entry->_bhfi))
00168                         entry->_bhfi_valid = true;
00169 
00170                     if (ScanNTFSStreams(entry, hFile))
00171                         entry->_scanned = true; // There exist named NTFS sub-streams in this file.
00172 
00173                     CloseHandle(hFile);
00174                 }
00175             }
00176 
00177             last = entry;   // There is always at least one entry, because FindFirstFile() succeeded and we don't filter the file entries.
00178         } while(FindNextFile(hFind, &w32fd));
00179 
00180         if (last)
00181             last->_next = NULL;
00182 
00183         FindClose(hFind);
00184     }
00185 
00186     _down = first_entry;
00187     _scanned = true;
00188 }
00189 
00190 
00191 const void* WinDirectory::get_next_path_component(const void* p) const
00192 {
00193     LPCTSTR s = (LPCTSTR) p;
00194 
00195     while(*s && *s!=TEXT('\\') && *s!=TEXT('/'))
00196         ++s;
00197 
00198     while(*s==TEXT('\\') || *s==TEXT('/'))
00199         ++s;
00200 
00201     if (!*s)
00202         return NULL;
00203 
00204     return s;
00205 }
00206 
00207 
00208 Entry* WinDirectory::find_entry(const void* p)
00209 {
00210     LPCTSTR name = (LPCTSTR)p;
00211 
00212     for(Entry*entry=_down; entry; entry=entry->_next) {
00213         LPCTSTR p = name;
00214         LPCTSTR q = entry->_data.cFileName;
00215 
00216         do {
00217             if (!*p || *p==TEXT('\\') || *p==TEXT('/'))
00218                 return entry;
00219         } while(tolower(*p++) == tolower(*q++));
00220 
00221         p = name;
00222         q = entry->_data.cAlternateFileName;
00223 
00224         do {
00225             if (!*p || *p==TEXT('\\') || *p==TEXT('/'))
00226                 return entry;
00227         } while(tolower(*p++) == tolower(*q++));
00228     }
00229 
00230     return NULL;
00231 }
00232 
00233 
00234  // get full path of specified directory entry
00235 bool WinEntry::get_path(PTSTR path, size_t path_count) const
00236 {
00237     return get_path_base(path, path_count, ET_WINDOWS);
00238 }
00239 
00240 ShellPath WinEntry::create_absolute_pidl() const
00241 {
00242     CONTEXT("WinEntry::create_absolute_pidl()");
00243 
00244     TCHAR path[MAX_PATH];
00245 
00246     if (get_path(path, COUNTOF(path)))
00247         return ShellPath(path);
00248 
00249     return ShellPath();
00250 }
00251 
00252 #endif // _NO_WIN_FS

Generated on Fri May 25 2012 04:16:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.