Public Member Functions

NtObjDirectory Struct Reference

NtObj file system directory-entry. More...

#include <ntobjfs.h>

Inheritance diagram for NtObjDirectory:
Inheritance graph
[legend]
Collaboration diagram for NtObjDirectory:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 NtObjDirectory (LPCTSTR root_path)
 NtObjDirectory (Entry *parent, LPCTSTR path)
 ~NtObjDirectory ()
virtual void read_directory (int scan_flags=0)
virtual Entryfind_entry (const void *)

Detailed Description

NtObj file system directory-entry.

Definition at line 100 of file ntobjfs.h.


Constructor & Destructor Documentation

NtObjDirectory::NtObjDirectory ( LPCTSTR  root_path ) [inline]

Definition at line 102 of file ntobjfs.h.

References Directory::_path.

Referenced by read_directory().

     :  NtObjEntry(DIRECTORY_OBJECT)
    {
        _path = _tcsdup(root_path);
    }

Here is the caller graph for this function:

NtObjDirectory::NtObjDirectory ( Entry parent,
LPCTSTR  path 
) [inline]

Definition at line 108 of file ntobjfs.h.

References Directory::_path.

     :  NtObjEntry(parent, DIRECTORY_OBJECT)
    {
        _path = _tcsdup(path);
    }
NtObjDirectory::~NtObjDirectory (  ) [inline]

Definition at line 114 of file ntobjfs.h.

References Directory::_path.

    {
        free(_path);
        _path = NULL;
    }

Member Function Documentation

Entry * NtObjDirectory::find_entry ( const void *  p ) [virtual]

Reimplemented from Entry.

Definition at line 359 of file ntobjfs.cpp.

References Entry::_data, Entry::_down, Entry::_next, and TEXT.

{
    LPCTSTR name = (LPCTSTR)p;

    for(Entry*entry=_down; entry; entry=entry->_next) {
        LPCTSTR p = name;
        LPCTSTR q = entry->_data.cFileName;

        do {
            if (!*p || *p==TEXT('\\') || *p==TEXT('/'))
                return entry;
        } while(tolower(*p++) == tolower(*q++));

        p = name;
        q = entry->_data.cAlternateFileName;

        do {
            if (!*p || *p==TEXT('\\') || *p==TEXT('/'))
                return entry;
        } while(tolower(*p++) == tolower(*q++));
    }

    return NULL;
}
void NtObjDirectory::read_directory ( int  scan_flags = 0 ) [virtual]

Reimplemented from Entry.

Definition at line 173 of file ntobjfs.cpp.

References Entry::_bhfi, Entry::_bhfi_valid, Entry::_content, Entry::_data, Entry::_down, Entry::_level, _MAX_PATH, Entry::_next, Directory::_path, Entry::_scanned, NtObjEntry::_type, Entry::_type_name, ATTRIBUTE_SYMBOLIC_LINK, CONTEXT, COUNTOF, DIRECTORY_OBJECT, KEY_OBJECT, NTDLL::NtClose, NtObjDirectory(), NtObjEntry::NtObjEntry(), NTDLL::NtQueryDirectoryObject, NTDLL::NtQueryObject, NTDLL::NtQuerySymbolicLinkObject, NTDLL::s_ObjectTypes, RtlUnicodeString::string_len, SYMBOLICLINK_OBJECT, TEXT, U2nA, UNKNOWN_OBJECT_TYPE, and wcsncpy_s.

{
    CONTEXT("NtObjDirectory::read_directory()");

    if (!g_NTDLL)
        g_NTDLL = new NTDLL();

    Entry* first_entry = NULL;
    int level = _level + 1;

    LPCTSTR path = (LPCTSTR)_path;

    TCHAR buffer[MAX_PATH], *p=buffer;
#ifndef UNICODE
    WCHAR wbuffer[MAX_PATH], *w=wbuffer;
#endif

    do {
        *p++ = *path;
#ifndef UNICODE
        *w++ = *path;
#endif
    } while(*path++);
    --p;
#ifndef UNICODE
    --w;
#endif

    DWORD idx;
    HANDLE dir_handle;

#ifdef UNICODE
    if (NtOpenObject(_type, &dir_handle, 0, buffer))
#else
    if (NtOpenObject(_type, &dir_handle, 0, wbuffer))
#endif
        return;

#ifdef UNICODE
    if (p[-1] != '\\')
        *p++ = '\\';
#else
    if (w[-1] != '\\')
        *w++ = '\\';
#endif

    NtObjectInfo* info = (NtObjectInfo*)alloca(2048);

    if (!(*g_NTDLL->NtQueryDirectoryObject)(dir_handle, info, 2048, TRUE, TRUE, &idx, NULL)) {
        WIN32_FIND_DATA w32fd;
        Entry* last = NULL;
        Entry* entry;

        do {
            memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));

#ifdef UNICODE
            if (info->name.string_ptr) {
                info->name.string_ptr[info->name.string_len / sizeof(WCHAR)] = 0;
            } else {
                TCHAR empty_string_ptr[] = _T("");
                info->name.string_ptr = empty_string_ptr;
            }
            if (info->type.string_ptr) {
                info->type.string_ptr[info->type.string_len / sizeof(WCHAR)] = 0;
            } else {
                TCHAR empty_string_ptr[] = _T("");
                info->type.string_ptr = empty_string_ptr;
            }
            lstrcpynW(p, info->name.string_ptr, COUNTOF(buffer));
#else
            WideCharToMultiByte(CP_ACP, 0, info->name.string_ptr, info->name.string_len, p, COUNTOF(buffer), 0, 0);
#endif

            lstrcpyn(w32fd.cFileName, p, sizeof(w32fd.cFileName) / sizeof(0[w32fd.cFileName]));

            const LPCWSTR* tname = NTDLL::s_ObjectTypes;
            OBJECT_TYPE type = UNKNOWN_OBJECT_TYPE;

            for(; *tname; tname++)
                if (!wcsncmp(info->type.string_ptr, *tname, 32))
                    {type=OBJECT_TYPE(tname-NTDLL::s_ObjectTypes); break;}

            if (type == DIRECTORY_OBJECT) {
                w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

                entry = new NtObjDirectory(this, buffer);
            }

            else if (type == SYMBOLICLINK_OBJECT) {
                w32fd.dwFileAttributes |= ATTRIBUTE_SYMBOLIC_LINK;

                entry = NULL;

#ifndef _NO_WIN_FS
                if (*w32fd.cFileName>='A' &&*w32fd.cFileName<='Z' && w32fd.cFileName[1]==':')
                    if (!_tcsncmp(buffer,TEXT("\\??\\"),4) ||       // NT4
                        !_tcsncmp(buffer,TEXT("\\GLOBAL??"),9)) {   // XP
                        w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
                        entry = new WinDirectory(this, w32fd.cFileName);
                    }
#endif

                if (!entry)
                    entry = new NtObjDirectory(this, buffer);
            }

            else if (type == KEY_OBJECT) {
                w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

                entry = new RegistryRoot(this, buffer);
            }
            else
                entry = new NtObjEntry(this, type);

            HANDLE handle;

#ifdef UNICODE
            lstrcpyW(p, info->name.string_ptr);
            if (!NtOpenObject(type, &handle, 0, buffer))
#else
            lstrcpyW(w, info->name.string_ptr);
            if (!NtOpenObject(type, &handle, 0, wbuffer))
#endif
            {
                NtObject object;
                DWORD read;

                if (!(*g_NTDLL->NtQueryObject)(handle, 0/*ObjectBasicInformation*/, &object, sizeof(NtObject), &read)) {
                    memcpy(&w32fd.ftCreationTime, &object.creation_time, sizeof(FILETIME));

                    memset(&entry->_bhfi, 0, sizeof(BY_HANDLE_FILE_INFORMATION));
                    entry->_bhfi.nNumberOfLinks = object.reference_count - 1;
                    entry->_bhfi_valid = true;
                }

                if (type == SYMBOLICLINK_OBJECT) {
                    WCHAR wbuffer[_MAX_PATH];
                    UnicodeString link(_MAX_PATH, wbuffer);

                    if (!(*g_NTDLL->NtQuerySymbolicLinkObject)(handle, &link, NULL)) {
                        int len = link.string_len/sizeof(WCHAR);
                        entry->_content = (LPTSTR) malloc((len+1)*sizeof(TCHAR));
#ifdef UNICODE
                        wcsncpy_s(entry->_content, len+1, link, len);
#else
                        U2nA(link, entry->_content, len);
#endif
                        entry->_content[len] = '\0';
                    }
                }

                (*g_NTDLL->NtClose)(handle);
            }

            memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));

#ifdef UNICODE
            entry->_type_name = _wcsdup(info->type.string_ptr);
#else
            char type_name[32];
            WideCharToMultiByte(CP_ACP, 0, info->type.string_ptr, info->type.string_len, type_name, 32, 0, 0);
            entry->_type_name = _strdup(type_name);
#endif

            if (!first_entry)
                first_entry = entry;

            if (last)
                last->_next = entry;

            entry->_level = level;

            last = entry;
        } while(!(*g_NTDLL->NtQueryDirectoryObject)(dir_handle, info, 2048, TRUE, FALSE, &idx, NULL));

        last->_next = NULL;
    }

    (*g_NTDLL->NtClose)(dir_handle);

    _down = first_entry;
    _scanned = true;
}

Here is the call graph for this function:


The documentation for this struct was generated from the following files:

ROS Explorer Source Code Documentation
generated on 02.01.2013 by doxygen

ROS Explorer Homepage