mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
basic support to display NTFS streams in winefile windows
svn path=/trunk/; revision=6865
This commit is contained in:
parent
558e83ae6a
commit
e8ecaa9aa1
10 changed files with 605 additions and 504 deletions
|
@ -1,10 +1,10 @@
|
|||
/* Do not edit - Machine generated */
|
||||
#ifndef _INC_REACTOS_BUILDNO
|
||||
#define _INC_REACTOS_BUILDNO
|
||||
#define KERNEL_VERSION_BUILD 0
|
||||
#define KERNEL_VERSION_BUILD_STR "0"
|
||||
#define KERNEL_RELEASE_RC "0.1.5.0\0"
|
||||
#define KERNEL_RELEASE_STR "0.1.5.0"
|
||||
#define KERNEL_VERSION_BUILD 11
|
||||
#define KERNEL_VERSION_BUILD_STR "11"
|
||||
#define KERNEL_RELEASE_RC "0.1.5.11\0"
|
||||
#define KERNEL_RELEASE_STR "0.1.5.11"
|
||||
#define KERNEL_VERSION_RC "0.1.5\0"
|
||||
#define KERNEL_VERSION_STR "0.1.5"
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
- Application Desktop Toolbars
|
||||
- desktop switching
|
||||
- command line in explorer windows
|
||||
- hide CVS subdirectories, may be even implement a CVS managment plugin
|
||||
- printer and RAS connection icons in desktop notification area
|
||||
- make task buttons smaller when running many applications
|
||||
- use multi threading for launching of programs and filling start menu subdirectories
|
||||
|
|
|
@ -47,3 +47,4 @@ If you search for more information, look into the CVS repository.
|
|||
18.10.2003 m. fuchs Program search dialog with interactive filtering and sorting does now work.
|
||||
19.10.2003 m. fuchs implemented floating start menus
|
||||
29.11.2003 m. fuchs implemented GDB stub for remote debugging
|
||||
06.12.2003 m. fuchs basic support to display NTFS streams in winefile windows
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<tr>
|
||||
<td><address style="align: right;"><small>
|
||||
ROS Explore Source Code Documentation
|
||||
<br>generated on 26.11.2003 by <a href="http://www.doxygen.org/index.html">
|
||||
<br>generated on 06.12.2003 by <a href="http://www.doxygen.org/index.html">
|
||||
<img src="doxygen.png" alt="doxygen" align="middle" border=0>
|
||||
</small></address>
|
||||
</td>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -200,7 +200,8 @@ bool FileChildWindow::expand_entry(Entry* dir)
|
|||
}
|
||||
|
||||
// no subdirectories ?
|
||||
if (!(p->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
if (!(p->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && // not a directory?
|
||||
!p->_down) // not a file with NTFS sub-streams?
|
||||
return FALSE;
|
||||
|
||||
idx = ListBox_FindItemData(_left_hwnd, 0, dir);
|
||||
|
@ -407,7 +408,9 @@ void FileChildWindow::activate_entry(Pane* pane, HWND hwnd)
|
|||
if (!entry)
|
||||
return;
|
||||
|
||||
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
if ((entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || // a directory?
|
||||
entry->_down) // a file with NTFS sub-streams?
|
||||
{
|
||||
int scanned_old = entry->_scanned;
|
||||
|
||||
if (!scanned_old)
|
||||
|
|
|
@ -408,7 +408,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
|
|||
|
||||
if (up->_next
|
||||
#ifndef _LEFT_FILES
|
||||
&& (up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
|
||||
&& ((up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) // a directory?
|
||||
|| up->_next->_down) // a file with NTFS sub-streams?
|
||||
#endif
|
||||
) {
|
||||
MoveToEx(dis->hDC, x, dis->rcItem.top, 0);
|
||||
|
@ -424,7 +425,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
|
|||
|
||||
if (entry->_next
|
||||
#ifndef _LEFT_FILES
|
||||
&& (entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
|
||||
&& ((entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) // a directory?
|
||||
|| entry->_next->_down) // a file with NTFS sub-streams?
|
||||
#endif
|
||||
)
|
||||
LineTo(dis->hDC, x, dis->rcItem.bottom);
|
||||
|
@ -661,7 +663,9 @@ void Pane::insert_entries(Entry* dir, int idx)
|
|||
|
||||
for(; entry; entry=entry->_next) {
|
||||
#ifndef _LEFT_FILES
|
||||
if (_treePane && !(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
|
||||
if (_treePane &&
|
||||
!(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && // not a directory?
|
||||
!entry->_down) // not a file with NTFS sub-streams?
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,6 +33,86 @@
|
|||
#include "winfs.h"
|
||||
|
||||
|
||||
int ScanNTFSStreams(Entry* entry, HANDLE hFile)
|
||||
{
|
||||
PVOID ctx = 0;
|
||||
DWORD read, seek_high;
|
||||
Entry** pnext = &entry->_down;
|
||||
int cnt = 0;
|
||||
|
||||
for(;;) {
|
||||
struct NTFS_StreamHdr : public WIN32_STREAM_ID {
|
||||
WCHAR name_padding[_MAX_FNAME]; // room for reading stream name
|
||||
} hdr;
|
||||
|
||||
if (!BackupRead(hFile, (LPBYTE)&hdr, (LPBYTE)&hdr.cStreamName-(LPBYTE)&hdr, &read, FALSE, FALSE, &ctx) || (long)read!=(LPBYTE)&hdr.cStreamName-(LPBYTE)&hdr)
|
||||
break;
|
||||
|
||||
if (hdr.dwStreamId == BACKUP_ALTERNATE_DATA) {
|
||||
if (hdr.dwStreamNameSize &&
|
||||
BackupRead(hFile, (LPBYTE)hdr.cStreamName, hdr.dwStreamNameSize, &read, FALSE, FALSE, &ctx) &&
|
||||
read==hdr.dwStreamNameSize)
|
||||
{
|
||||
++cnt;
|
||||
|
||||
int l = hdr.dwStreamNameSize / sizeof(WCHAR);
|
||||
LPCWSTR p = hdr.cStreamName;
|
||||
LPCWSTR e = hdr.cStreamName + l;
|
||||
|
||||
if (l>0 && *p==':') {
|
||||
++p, --l;
|
||||
|
||||
e = p;
|
||||
|
||||
while(l>0 && *e!=':')
|
||||
++e, --l;
|
||||
|
||||
l = e - p;
|
||||
}
|
||||
|
||||
Entry* stream_entry = new WinEntry(entry);
|
||||
|
||||
memcpy(&stream_entry->_data, &entry->_data, sizeof(WIN32_FIND_DATA));
|
||||
|
||||
lstrcpy(stream_entry->_data.cFileName, String(p, l));
|
||||
|
||||
stream_entry->_down = NULL;
|
||||
stream_entry->_expanded = false;
|
||||
stream_entry->_scanned = false;
|
||||
stream_entry->_level = entry->_level + 1;
|
||||
stream_entry->_bhfi_valid = false;
|
||||
|
||||
*pnext = stream_entry;
|
||||
pnext = &stream_entry->_next;
|
||||
}
|
||||
} else if (hdr.dwStreamId == BACKUP_SPARSE_BLOCK) {
|
||||
DWORD sparse_buffer[2];
|
||||
|
||||
if (!BackupRead(hFile, (LPBYTE)&sparse_buffer, 8, &read, FALSE, FALSE, &ctx)) {
|
||||
BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx);
|
||||
THROW_EXCEPTION(GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
// jump to the next stream header
|
||||
if (!BackupSeek(hFile, ~0, ~0, &read, &seek_high, &ctx)) {
|
||||
DWORD error = GetLastError();
|
||||
|
||||
if (error != ERROR_SEEK) {
|
||||
BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx);
|
||||
THROW_EXCEPTION(error);
|
||||
//break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!BackupRead(hFile, 0, 0, &read, TRUE, FALSE, &ctx))
|
||||
THROW_EXCEPTION(GetLastError());
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
void WinDirectory::read_directory()
|
||||
{
|
||||
Entry* first_entry = NULL;
|
||||
|
@ -80,6 +160,9 @@ void WinDirectory::read_directory()
|
|||
if (GetFileInformationByHandle(hFile, &entry->_bhfi))
|
||||
entry->_bhfi_valid = true;
|
||||
|
||||
if (ScanNTFSStreams(entry, hFile))
|
||||
entry->_scanned = true; // There exist named NTFS sub-streams in this file.
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
|
@ -158,7 +241,10 @@ void WinEntry::get_path(PTSTR path) const
|
|||
memcpy(path+1, name, l*sizeof(TCHAR));
|
||||
len += l+1;
|
||||
|
||||
path[0] = TEXT('\\');
|
||||
if (entry->_up && !(entry->_up->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) // a NTFS stream?
|
||||
path[0] = TEXT(':');
|
||||
else
|
||||
path[0] = TEXT('\\');
|
||||
}
|
||||
|
||||
entry = entry->_up;
|
||||
|
|
|
@ -144,7 +144,8 @@ struct COMException : public COMExceptionBase
|
|||
int _line;
|
||||
};
|
||||
|
||||
#define CHECKERROR(hr) ((void)(FAILED(hr)? throw COMException(hr, __FILE__, __LINE__): 0))
|
||||
#define THROW_EXCEPTION(e) throw COMException(e, __FILE__, __LINE__)
|
||||
#define CHECKERROR(hr) ((void)(FAILED(hr)? THROW_EXCEPTION(hr): 0))
|
||||
|
||||
|
||||
#ifdef _NO_COMUTIL
|
||||
|
|
|
@ -581,19 +581,24 @@ struct String
|
|||
|
||||
String() {}
|
||||
String(LPCTSTR s) : super(s) {}
|
||||
String(LPCTSTR s, int l) : super(s, l) {}
|
||||
String(const super& other) : super(other) {}
|
||||
String(const String& other) : super(other) {}
|
||||
|
||||
#ifdef UNICODE
|
||||
String(LPCSTR s) {assign(s);}
|
||||
String(LPCSTR s, int l) {assign(s, l);}
|
||||
String(const string& other) {assign(other.c_str());}
|
||||
String& operator=(LPCSTR s) {assign(s); return *this;}
|
||||
void assign(LPCSTR s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN));}
|
||||
void assign(LPCSTR s, int l) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, BUFFER_LEN));}
|
||||
#else
|
||||
String(LPCWSTR s) {assign(s);}
|
||||
String(LPCWSTR s, int l) {assign(s, l);}
|
||||
String(const wstring& other) {assign(other.c_str());}
|
||||
String& operator=(LPCWSTR s) {assign(s); return *this;}
|
||||
void assign(LPCWSTR s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0));}
|
||||
void assign(LPCWSTR s, int l) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));}
|
||||
#endif
|
||||
|
||||
String& operator=(LPCTSTR s) {super::assign(s); return *this;}
|
||||
|
|
Loading…
Reference in a new issue