Author: dquintana
Date: Sat Feb 21 21:21:02 2015
New Revision: 66396
URL:
http://svn.reactos.org/svn/reactos?rev=66396&view=rev
Log:
[NTOBJSHEX]
* Introduce a shell extension that allows the user to browse the NT Object namespace from
within the shell.
CORE-9243 #resolve
Added:
trunk/reactos/dll/shellext/ntobjshex/ (with props)
trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt (with props)
trunk/reactos/dll/shellext/ntobjshex/lang/ (with props)
trunk/reactos/dll/shellext/ntobjshex/lang/en-US.rc (with props)
trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp (with props)
trunk/reactos/dll/shellext/ntobjshex/ntobjns.h (with props)
trunk/reactos/dll/shellext/ntobjshex/ntobjshex.cpp (with props)
trunk/reactos/dll/shellext/ntobjshex/ntobjshex.rc (with props)
trunk/reactos/dll/shellext/ntobjshex/ntobjshex.spec (with props)
trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp (with props)
trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h (with props)
trunk/reactos/dll/shellext/ntobjshex/precomp.h (with props)
trunk/reactos/dll/shellext/ntobjshex/resource.h (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/ (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/1.ico (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/2.ico (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/3.ico (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/4.ico (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/5.ico (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/6.ico (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/rgs/ (with props)
trunk/reactos/dll/shellext/ntobjshex/resources/rgs/ntobjectfolder.rgs (with props)
Modified:
trunk/reactos/dll/shellext/CMakeLists.txt
trunk/reactos/dll/shellext/netshell/CMakeLists.txt
trunk/reactos/include/reactos/shellutils.h
Modified: trunk/reactos/dll/shellext/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/CMakeLists.tx…
==============================================================================
--- trunk/reactos/dll/shellext/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/CMakeLists.txt [iso-8859-1] Sat Feb 21 21:21:02 2015
@@ -4,5 +4,6 @@
add_subdirectory(devcpux)
add_subdirectory(fontext)
add_subdirectory(netshell)
+add_subdirectory(ntobjshex)
add_subdirectory(slayer)
add_subdirectory(stobject)
Modified: trunk/reactos/dll/shellext/netshell/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/netshell/CMak…
==============================================================================
--- trunk/reactos/dll/shellext/netshell/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/netshell/CMakeLists.txt [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -24,6 +24,9 @@
lanstatusui.cpp
precomp.h)
+list(APPEND atl_rc_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/resources/rgs/ntobjectfolder.rgs)
+
add_library(netshell SHARED
${SOURCE}
netshell.rc
Propchange: trunk/reactos/dll/shellext/ntobjshex/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Sat Feb 21 21:21:02 2015
@@ -0,0 +1 @@
+((CORE|ROSTESTS|ROSAPPS)-\d+)(,? ?((CORE|ROSTESTS|ROSAPPS)-\d+))*(,? ?(and |or
)?((CORE|ROSTESTS|ROSAPPS)-\d+))?
Propchange: trunk/reactos/dll/shellext/ntobjshex/
------------------------------------------------------------------------------
bugtraq:message = See issue %BUGID% for more details.
Propchange: trunk/reactos/dll/shellext/ntobjshex/
------------------------------------------------------------------------------
bugtraq:url =
https://jira.reactos.org/browse/%BUGID%
Propchange: trunk/reactos/dll/shellext/ntobjshex/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/CMa…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt (added)
+++ trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,41 @@
+
+project(SHELL)
+
+set_cpp(WITH_RUNTIME)
+
+if(NOT MSVC)
+ # HACK: this should be enabled globally!
+ add_compile_flags_language("-std=c++11" "CXX")
+endif()
+
+include_directories(
+ ${REACTOS_SOURCE_DIR}/lib/atl
+ ${REACTOS_SOURCE_DIR})
+
+spec2def(ntobjshex.dll ntobjshex.spec)
+
+add_library(ntobjshex SHARED
+ ntobjns.cpp
+ ntobjshex.cpp
+ ntobjutil.cpp
+ ntobjshex.rc
+ ${CMAKE_CURRENT_BINARY_DIR}/ntobjshex.def)
+
+set_module_type(ntobjshex win32dll UNICODE)
+target_link_libraries(ntobjshex uuid wine atlnew)
+
+add_importlibs(ntobjshex
+ advapi32
+ winmm
+ ole32
+ oleaut32
+ shlwapi
+ shell32
+ comctl32
+ msvcrt
+ gdi32
+ user32
+ kernel32
+ ntdll)
+
+add_cd_file(TARGET ntobjshex DESTINATION reactos/system32 FOR all)
Propchange: trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/reactos/dll/shellext/ntobjshex/lang/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Sat Feb 21 21:21:02 2015
@@ -0,0 +1 @@
+((CORE|ROSTESTS|ROSAPPS)-\d+)(,? ?((CORE|ROSTESTS|ROSAPPS)-\d+))*(,? ?(and |or
)?((CORE|ROSTESTS|ROSAPPS)-\d+))?
Propchange: trunk/reactos/dll/shellext/ntobjshex/lang/
------------------------------------------------------------------------------
bugtraq:message = See issue %BUGID% for more details.
Propchange: trunk/reactos/dll/shellext/ntobjshex/lang/
------------------------------------------------------------------------------
bugtraq:url =
https://jira.reactos.org/browse/%BUGID%
Propchange: trunk/reactos/dll/shellext/ntobjshex/lang/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/dll/shellext/ntobjshex/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/lan…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/lang/en-US.rc (added)
+++ trunk/reactos/dll/shellext/ntobjshex/lang/en-US.rc [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,6 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+ IDS_NAME "NT Object Namespace"
+END
Propchange: trunk/reactos/dll/shellext/ntobjshex/lang/en-US.rc
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp (added)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,1253 @@
+/*
+* PROJECT: ReactOS shell extensions
+* LICENSE: GPL - See COPYING in the top level directory
+* FILE: dll\shellext\ntobjshex\ntobjns.cpp
+* PURPOSE: NT Object Namespace shell extension
+* PROGRAMMERS: David Quintana <gigaherz(a)gmail.com>
+*/
+
+#include "precomp.h"
+#include "ntobjutil.h"
+#include <ntquery.h>
+
+#define SHCIDS_ALLFIELDS 0x80000000L
+#define SHCIDS_CANONICALONLY 0x10000000L
+
+#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
+#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
+
+WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
+
+// {845B0FB2-66E0-416B-8F91-314E23F7C12D}
+const GUID CLSID_NtObjectFolder = { 0x845b0fb2, 0x66e0, 0x416b, { 0x8f, 0x91, 0x31, 0x4e,
0x23, 0xf7, 0xc1, 0x2d } };
+
+// {F4C430C3-3A8D-4B56-A018-E598DA60C2E0}
+static const GUID GUID_NtObjectColumns = { 0xf4c430c3, 0x3a8d, 0x4b56, { 0xa0, 0x18,
0xe5, 0x98, 0xda, 0x60, 0xc2, 0xe0 } };
+
+enum NtObjectColumns
+{
+ PID_NTOBJECT_NAME = 1,
+ PID_NTOBJECT_TYPE = 2,
+ PID_NTOBJECT_CREATEDATE = 3,
+ PID_NTOBJECT_LINKTARGET = 4,
+};
+
+static HRESULT MakeStrRetFromString(LPCWSTR string, DWORD cbLength, STRRET * str)
+{
+ str->uType = STRRET_WSTR;
+
+ DWORD blen = cbLength + sizeof(WCHAR);
+ str->pOleStr = (LPWSTR) CoTaskMemAlloc(blen);
+ return StringCbCopyNW(str->pOleStr, blen, string, cbLength);
+}
+
+static HRESULT MakeStrRetFromString(LPCWSTR string, STRRET * str)
+{
+ DWORD stringLength = lstrlenW(string) * sizeof(WCHAR);
+ return MakeStrRetFromString(string, stringLength, str);
+}
+
+static HRESULT MakeVariantString(VARIANT * pv, PCWSTR string)
+{
+ V_VT(pv) = VT_BSTR;
+ V_BSTR(pv) = SysAllocString(string);
+ return S_OK;
+}
+
+static HRESULT GetFullName(LPCITEMIDLIST pidl, DWORD uFlags, PWSTR strName, DWORD
cchName)
+{
+ CComPtr<IShellFolder> psfDesktop;
+ STRRET str;
+ HRESULT hr;
+
+ hr = SHGetDesktopFolder(&psfDesktop);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ hr = psfDesktop->GetDisplayNameOf(pidl, uFlags, &str);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return StrRetToBufW(&str, pidl, strName, cchName);
+}
+
+class CNtObjectFolderContextMenu :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IContextMenu
+{
+ LPCITEMIDLIST pcidlFolder;
+ LPCITEMIDLIST pcidlChild;
+ UINT idFirst;
+
+public:
+ CNtObjectFolderContextMenu() :
+ pcidlFolder(NULL),
+ pcidlChild(NULL),
+ idFirst(0)
+ {
+
+ }
+
+ virtual ~CNtObjectFolderContextMenu()
+ {
+ if (pcidlFolder)
+ ILFree((LPITEMIDLIST) pcidlFolder);
+ if (pcidlChild)
+ ILFree((LPITEMIDLIST) pcidlChild);
+ }
+
+ HRESULT Initialize(LPITEMIDLIST parent, UINT cidl, LPCITEMIDLIST *apidl)
+ {
+ pcidlFolder = ILClone(parent);
+ if (cidl != 1)
+ return E_FAIL;
+ pcidlChild = ILClone(apidl[0]);
+ return S_OK;
+ }
+
+ // IContextMenu
+ virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags)
+ {
+ idFirst = idCmdFirst;
+
+ const NtPidlEntry * entry = (NtPidlEntry *) pcidlChild;
+
+ if ((entry->objectType == DIRECTORY_OBJECT) ||
+ (entry->objectType == SYMBOLICLINK_OBJECT))
+ {
+ MENUITEMINFOW mii;
+
+ WCHAR open [] = L"Open";
+ WCHAR opennewwindow [] = L"Open in new window";
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
+ mii.fType = MFT_STRING;
+ mii.wID = idCmdFirst++;
+ mii.dwTypeData = open;
+ mii.cch = _countof(open);
+ mii.fState = MFS_ENABLED | MFS_DEFAULT;
+ mii.hSubMenu = NULL;
+ InsertMenuItemW(hmenu, idCmdFirst, TRUE, &mii);
+
+ if (!(uFlags & CMF_DEFAULTONLY) && idCmdFirst <= idCmdLast)
+ {
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
+ mii.fType = MFT_STRING;
+ mii.wID = idCmdFirst++;
+ mii.dwTypeData = opennewwindow;
+ mii.cch = _countof(opennewwindow);
+ mii.fState = MFS_ENABLED;
+ mii.hSubMenu = NULL;
+ InsertMenuItemW(hmenu, idCmdFirst, FALSE, &mii);
+ }
+ }
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdFirst - idFirst);
+ }
+
+ virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
+ {
+ if (LOWORD(lpici->lpVerb) == idFirst || !lpici->lpVerb)
+ {
+ LPITEMIDLIST fullPidl = ILCombine(pcidlFolder, pcidlChild);
+
+ SHELLEXECUTEINFO sei = { 0 };
+ sei.cbSize = sizeof(sei);
+ sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
+ sei.lpIDList = fullPidl;
+ sei.lpClass = L"folder";
+ sei.hwnd = lpici->hwnd;
+ sei.nShow = lpici->nShow;
+ sei.lpVerb = L"open";
+ BOOL bRes = ::ShellExecuteEx(&sei);
+
+ ILFree(fullPidl);
+
+ return bRes ? S_OK : HRESULT_FROM_WIN32(GetLastError());
+ }
+ else if (LOWORD(lpici->lpVerb) == (idFirst + 1))
+ {
+ LPITEMIDLIST fullPidl = ILCombine(pcidlFolder, pcidlChild);
+
+ SHELLEXECUTEINFO sei = { 0 };
+ sei.cbSize = sizeof(sei);
+ sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
+ sei.lpIDList = fullPidl;
+ sei.lpClass = L"folder";
+ sei.hwnd = lpici->hwnd;
+ sei.nShow = lpici->nShow;
+ sei.lpVerb = L"opennewwindow";
+ BOOL bRes = ::ShellExecuteEx(&sei);
+
+ ILFree(fullPidl);
+
+ return bRes ? S_OK : HRESULT_FROM_WIN32(GetLastError());
+ }
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved,
LPSTR pszName, UINT cchMax)
+ {
+ if (idCmd == idFirst)
+ {
+ if (uType == GCS_VERBW)
+ {
+ StringCchCopyW((LPWSTR) pszName, cchMax, L"open");
+ return S_OK;
+ }
+ }
+ else if (idCmd == (idFirst + 1))
+ {
+ if (uType == GCS_VERBW)
+ {
+ StringCchCopyW((LPWSTR) pszName, cchMax, L"opennewwindow");
+ return S_OK;
+ }
+ }
+ return E_NOTIMPL;
+ }
+
+ DECLARE_NOT_AGGREGATABLE(CNtObjectFolderContextMenu)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CNtObjectFolderContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ END_COM_MAP()
+
+};
+
+class CNtObjectFolderExtractIcon :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IExtractIconW
+{
+ LPCITEMIDLIST pcidlFolder;
+ LPCITEMIDLIST pcidlChild;
+
+public:
+ CNtObjectFolderExtractIcon() :
+ pcidlFolder(NULL),
+ pcidlChild(NULL)
+ {
+
+ }
+
+ virtual ~CNtObjectFolderExtractIcon()
+ {
+ if (pcidlFolder)
+ ILFree((LPITEMIDLIST) pcidlFolder);
+ if (pcidlChild)
+ ILFree((LPITEMIDLIST) pcidlChild);
+ }
+
+ HRESULT Initialize(LPITEMIDLIST parent, UINT cidl, LPCITEMIDLIST *apidl)
+ {
+ pcidlFolder = ILClone(parent);
+ if (cidl != 1)
+ return E_FAIL;
+ pcidlChild = ILClone(apidl[0]);
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE GetIconLocation(
+ UINT uFlags,
+ LPWSTR szIconFile,
+ UINT cchMax,
+ INT *piIndex,
+ UINT *pwFlags)
+ {
+ const NtPidlEntry * entry = (NtPidlEntry *) pcidlChild;
+ if (entry->magic != NT_OBJECT_PIDL_MAGIC)
+ return E_FAIL;
+
+ switch (entry->objectType)
+ {
+ case DIRECTORY_OBJECT:
+ case SYMBOLICLINK_OBJECT:
+ GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
+ *piIndex = -((uFlags & GIL_OPENICON) ? IDI_NTOBJECTDIROPEN :
IDI_NTOBJECTDIR);
+ *pwFlags = 0;
+ return S_OK;
+ case DEVICE_OBJECT:
+ GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
+ *piIndex = -IDI_NTOBJECTDEVICE;
+ *pwFlags = 0;
+ return S_OK;
+ case PORT_OBJECT:
+ GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
+ *piIndex = -IDI_NTOBJECTPORT;
+ *pwFlags = 0;
+ return S_OK;
+ default:
+ GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
+ *piIndex = -IDI_NTOBJECTITEM;
+ *pwFlags = 0;
+ return S_OK;
+ }
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Extract(
+ LPCWSTR pszFile,
+ UINT nIconIndex,
+ HICON *phiconLarge,
+ HICON *phiconSmall,
+ UINT nIconSize)
+ {
+ return SHDefExtractIconW(pszFile, nIconIndex, 0, phiconLarge, phiconSmall,
nIconSize);
+ }
+
+ DECLARE_NOT_AGGREGATABLE(CNtObjectFolderExtractIcon)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CNtObjectFolderExtractIcon)
+ COM_INTERFACE_ENTRY_IID(IID_IExtractIconW, IExtractIconW)
+ END_COM_MAP()
+
+};
+
+class CNtObjectPidlManager
+{
+private:
+ PWSTR m_ntPath;
+
+ HDPA m_hDpa;
+ UINT m_hDpaCount;
+
+ int DpaDeleteCallback(NtPidlEntry * info)
+ {
+ CoTaskMemFree(info);
+ return 0;
+ }
+
+ static int CALLBACK s_DpaDeleteCallback(void *pItem, void *pData)
+ {
+ CNtObjectPidlManager * mf = (CNtObjectPidlManager*) pData;
+ NtPidlEntry * item = (NtPidlEntry*) pItem;
+ return mf->DpaDeleteCallback(item);
+ }
+
+public:
+ CNtObjectPidlManager() :
+ m_ntPath(NULL),
+ m_hDpa(NULL),
+ m_hDpaCount(0)
+ {
+ }
+
+ ~CNtObjectPidlManager()
+ {
+ DPA_DestroyCallback(m_hDpa, s_DpaDeleteCallback, this);
+ }
+
+ HRESULT Initialize(PWSTR ntPath)
+ {
+ m_ntPath = ntPath;
+
+ m_hDpa = DPA_Create(10);
+
+ if (!m_hDpa)
+ return E_FAIL;
+
+ HRESULT hr = EnumerateNtDirectory(m_hDpa, m_ntPath, &m_hDpaCount);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return S_OK;
+ }
+
+ HRESULT FindPidlInList(LPCITEMIDLIST pcidl, NtPidlEntry ** pinfo)
+ {
+ HRESULT hr;
+
+ if (!m_hDpa)
+ {
+ return E_FAIL;
+ }
+
+ TRACE("Searching for pidl { cb=%d } in a list of %d items\n",
pcidl->mkid.cb, m_hDpaCount);
+
+ for (int i = 0; i < (int) m_hDpaCount; i++)
+ {
+ NtPidlEntry * pInfo = (NtPidlEntry *) DPA_GetPtr(m_hDpa, i);
+ if (!pInfo)
+ return E_FAIL;
+
+ hr = CompareIDs(0, pInfo, pcidl);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (hr == S_OK)
+ {
+ *pinfo = pInfo;
+ return S_OK;
+ }
+ else
+ {
+ TRACE("Comparison returned %d\n", (int) (short) (hr &
0xFFFF));
+ }
+ }
+
+ TRACE("Pidl not found\n");
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+
+ HRESULT FindByName(LPCWSTR strParsingName, NtPidlEntry ** pinfo)
+ {
+ if (!m_hDpa)
+ {
+ return E_FAIL;
+ }
+
+ TRACE("Searching for '%S' in a list of %d items\n",
strParsingName, m_hDpaCount);
+
+ for (int i = 0; i < (int) m_hDpaCount; i++)
+ {
+ NtPidlEntry * pInfo = (NtPidlEntry *) DPA_GetPtr(m_hDpa, i);
+ if (!pInfo)
+ return E_FAIL;
+
+ int order = CompareStringW(GetThreadLocale(), NORM_IGNORECASE,
+ pInfo->entryName, lstrlenW(pInfo->entryName),
+ strParsingName, lstrlenW(strParsingName));
+
+ if (order == CSTR_EQUAL)
+ {
+ *pinfo = pInfo;
+ return S_OK;
+ }
+ }
+
+ TRACE("Pidl not found\n");
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+
+ HRESULT GetPidl(UINT index, NtPidlEntry ** pEntry)
+ {
+ *pEntry = NULL;
+
+ NtPidlEntry * entry = (NtPidlEntry *) DPA_GetPtr(m_hDpa, index);
+ if (!entry)
+ {
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+
+ *pEntry = entry;
+ return S_OK;
+ }
+
+ HRESULT GetCount(UINT * count)
+ {
+ *count = m_hDpaCount;
+ return S_OK;
+ }
+
+
+ static LPITEMIDLIST CreatePidlFromItem(NtPidlEntry * entry)
+ {
+ LPITEMIDLIST idl = (LPITEMIDLIST) CoTaskMemAlloc(entry->cb + 2);
+ if (!idl)
+ return NULL;
+ memset(idl, 0, entry->cb + 2);
+ memcpy(idl, entry, entry->cb);
+ return idl;
+ }
+
+ HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, NtPidlEntry * second)
+ {
+ if (LOWORD(lParam) != 0)
+ return E_FAIL;
+
+ if (second->cb > first->cb)
+ return MAKE_HRESULT(0, 0, (USHORT) 1);
+ if (second->cb < first->cb)
+ return MAKE_HRESULT(0, 0, (USHORT) -1);
+
+ if (second->entryNameLength > first->entryNameLength)
+ return MAKE_HRESULT(0, 0, (USHORT) 1);
+ if (second->entryNameLength < first->entryNameLength)
+ return MAKE_HRESULT(0, 0, (USHORT) -1);
+
+ if (HIWORD(lParam) == SHCIDS_ALLFIELDS)
+ {
+ int ord = memcmp(second, first, first->cb);
+
+ if (ord != 0)
+ return MAKE_HRESULT(0, 0, (USHORT) ord);
+ }
+ else if (HIWORD(lParam) == SHCIDS_CANONICALONLY)
+ {
+ int ord = StrCmpNW(second->entryName, first->entryName,
first->entryNameLength);
+
+ if (ord != 0)
+ return MAKE_HRESULT(0, 0, (USHORT) ord);
+ }
+ else
+ {
+ int ord = (int) second->objectType - (int) first->objectType;
+
+ if (ord > 0)
+ return MAKE_HRESULT(0, 0, (USHORT) 1);
+ if (ord < 0)
+ return MAKE_HRESULT(0, 0, (USHORT) -1);
+
+ ord = StrCmpNW(second->entryName, first->entryName,
first->entryNameLength/sizeof(WCHAR));
+
+ if (ord != 0)
+ return MAKE_HRESULT(0, 0, (USHORT) ord);
+ }
+
+ return S_OK;
+ }
+
+ HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, LPCITEMIDLIST pcidl)
+ {
+ LPCITEMIDLIST p = (pcidl);
+ NtPidlEntry * second = (NtPidlEntry*) &(p->mkid);
+ if (second->magic != NT_OBJECT_PIDL_MAGIC)
+ return E_FAIL;
+
+ return CompareIDs(lParam, first, second);
+ }
+
+ HRESULT CompareIDs(LPARAM lParam, LPCITEMIDLIST pcidl1, LPCITEMIDLIST pcidl2)
+ {
+ LPCITEMIDLIST p = (pcidl1);
+ NtPidlEntry * first = (NtPidlEntry*) &(p->mkid);
+ if (first->magic != NT_OBJECT_PIDL_MAGIC)
+ return E_FAIL;
+
+ return CompareIDs(lParam, first, pcidl2);
+ }
+
+ ULONG ConvertAttributes(OBJECT_TYPE Type, ULONG Attributes, PULONG inMask)
+ {
+ ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
+ ULONG flags = 0;
+
+ if (Type == DIRECTORY_OBJECT)
+ flags |= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+
+ if (Type == SYMBOLICLINK_OBJECT)
+ flags |= SFGAO_LINK | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+
+ return flags & mask;
+ }
+
+};
+
+class CNtObjectFolderEnum :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IEnumIDList
+{
+private:
+ CComPtr<CNtObjectFolder> m_Folder;
+
+ HWND m_HwndOwner;
+ SHCONTF m_Flags;
+
+ UINT m_Index;
+ UINT m_Count;
+
+public:
+ CNtObjectFolderEnum() :
+ m_HwndOwner(NULL),
+ m_Flags(0),
+ m_Index(0),
+ m_Count(0)
+ {
+ }
+
+ virtual ~CNtObjectFolderEnum()
+ {
+ }
+
+ HRESULT Initialize(CNtObjectFolder * folder, HWND hwndOwner, SHCONTF flags)
+ {
+ m_Folder = folder;
+
+ m_Folder->GetManager().GetCount(&m_Count);
+
+ m_HwndOwner = hwndOwner;
+ m_Flags = flags;
+
+ return Reset();
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Next(
+ ULONG celt,
+ LPITEMIDLIST *rgelt,
+ ULONG *pceltFetched)
+ {
+ if (pceltFetched)
+ *pceltFetched = 0;
+
+ if (m_Index >= m_Count)
+ return S_FALSE;
+
+ for (int i = 0; i < (int) celt;)
+ {
+ NtPidlEntry * tinfo;
+ BOOL flagsOk = FALSE;
+
+ do {
+ HRESULT hr = m_Folder->GetManager().GetPidl(m_Index++, &tinfo);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ switch (tinfo->objectType)
+ {
+ case SYMBOLICLINK_OBJECT:
+ case DIRECTORY_OBJECT:
+ flagsOk = (m_Flags & SHCONTF_FOLDERS) != 0;
+ break;
+ default:
+ flagsOk = (m_Flags & SHCONTF_NONFOLDERS) != 0;
+ break;
+ }
+ } while (m_Index < m_Count && !flagsOk);
+
+ if (m_Index < m_Count)
+ {
+ if (rgelt)
+ rgelt[i] = m_Folder->GetManager().CreatePidlFromItem(tinfo);
+ i++;
+ }
+
+ if (m_Index == m_Count)
+ {
+ if (pceltFetched)
+ *pceltFetched = i;
+ return (i == (int) celt) ? S_OK : S_FALSE;
+ }
+ }
+
+ if (pceltFetched) *pceltFetched = celt;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
+ {
+ return Next(celt, NULL, NULL);
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Reset()
+ {
+ m_Index = 0;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
+ {
+ return ShellObjectCreatorInit<CNtObjectFolderEnum>(m_Folder, m_HwndOwner,
m_Flags, IID_PPV_ARG(IEnumIDList, ppenum));
+ }
+
+ DECLARE_NOT_AGGREGATABLE(CNtObjectFolderEnum)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CNtObjectFolderEnum)
+ COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+ END_COM_MAP()
+
+};
+
+//-----------------------------------------------------------------------------
+// CNtObjectFolder
+
+extern "C"
+HRESULT WINAPI CMergedFolder_Constructor(REFIID riid, LPVOID *ppv)
+{
+ return ShellObjectCreator<CNtObjectFolder>(riid, ppv);
+}
+
+CNtObjectFolder::CNtObjectFolder() :
+ m_PidlManager(NULL),
+ m_shellPidl(NULL)
+{
+}
+
+CNtObjectFolder::~CNtObjectFolder()
+{
+}
+
+// IShellFolder
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::ParseDisplayName(
+ HWND hwndOwner,
+ LPBC pbcReserved,
+ LPOLESTR lpszDisplayName,
+ ULONG *pchEaten,
+ LPITEMIDLIST *ppidl,
+ ULONG *pdwAttributes)
+{
+ HRESULT hr;
+ NtPidlEntry * info;
+
+ if (!ppidl)
+ return E_FAIL;
+
+ if (pchEaten)
+ *pchEaten = 0;
+
+ if (pdwAttributes)
+ *pdwAttributes = 0;
+
+ TRACE("ParseDisplayName name=%S\n", lpszDisplayName);
+
+ hr = m_PidlManager->FindByName(lpszDisplayName, &info);
+ if (FAILED(hr))
+ {
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+
+ *ppidl = m_PidlManager->CreatePidlFromItem(info);
+
+ if (pchEaten)
+ *pchEaten = lstrlenW(info->entryName);
+
+ if (pdwAttributes)
+ *pdwAttributes = m_PidlManager->ConvertAttributes(info->objectType,
info->objectInformation.Attributes, pdwAttributes);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::EnumObjects(
+ HWND hwndOwner,
+ SHCONTF grfFlags,
+ IEnumIDList **ppenumIDList)
+{
+ return ShellObjectCreatorInit<CNtObjectFolderEnum>(this, hwndOwner, grfFlags,
IID_PPV_ARG(IEnumIDList, ppenumIDList));
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
+ LPCITEMIDLIST pidl,
+ LPBC pbcReserved,
+ REFIID riid,
+ void **ppvOut)
+{
+ NtPidlEntry * info;
+ HRESULT hr;
+
+ if (IsEqualIID(riid, IID_IShellFolder))
+ {
+ hr = m_PidlManager->FindPidlInList(pidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (!(info->objectInformation.GrantedAccess & (STANDARD_RIGHTS_READ |
FILE_LIST_DIRECTORY)))
+ return E_ACCESSDENIED;
+
+ LPITEMIDLIST fullPidl = ILCombine(m_shellPidl, pidl);
+
+ WCHAR path[MAX_PATH];
+
+ if (info->objectType == SYMBOLICLINK_OBJECT)
+ {
+ NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+
+ if (symlink->targetNameLength > 0)
+ {
+ StringCbCopyW(path, _countof(path), symlink->targetName);
+ }
+ else
+ {
+ return E_FAIL;
+ }
+ }
+ else
+ {
+ StringCbCopyW(path, _countof(path), m_NtPath);
+
+ PathAppendW(path, info->entryName);
+
+ DbgPrint("BindToObject for Directory %S\n", path);
+ }
+
+ return ShellObjectCreatorInit<CNtObjectFolder>(fullPidl, path, riid,
ppvOut);
+ }
+
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToStorage(
+ LPCITEMIDLIST pidl,
+ LPBC pbcReserved,
+ REFIID riid,
+ void **ppvObj)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::CompareIDs(
+ LPARAM lParam,
+ LPCITEMIDLIST pidl1,
+ LPCITEMIDLIST pidl2)
+{
+ TRACE("CompareIDs\n");
+ return m_PidlManager->CompareIDs(lParam, pidl1, pidl2);
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::CreateViewObject(
+ HWND hwndOwner,
+ REFIID riid,
+ void **ppvOut)
+{
+ if (!IsEqualIID(riid, IID_IShellView))
+ return E_NOINTERFACE;
+
+ SFV_CREATE sfv;
+ sfv.cbSize = sizeof(sfv);
+ sfv.pshf = this;
+ sfv.psvOuter = NULL;
+ sfv.psfvcb = NULL;
+
+ return SHCreateShellFolderView(&sfv, (IShellView**) ppvOut);
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetAttributesOf(
+ UINT cidl,
+ LPCITEMIDLIST *apidl,
+ SFGAOF *rgfInOut)
+{
+ NtPidlEntry * info;
+ HRESULT hr;
+
+ TRACE("GetAttributesOf\n");
+
+ if (cidl == 0)
+ {
+ *rgfInOut &= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+ return S_OK;
+ }
+
+ for (int i = 0; i < (int) cidl; i++)
+ {
+ LPCITEMIDLIST pidl = apidl[i];
+
+ hr = m_PidlManager->FindPidlInList(pidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ // Update attributes.
+ *rgfInOut = m_PidlManager->ConvertAttributes(info->objectType,
info->objectInformation.Attributes, rgfInOut);
+ }
+
+ return S_OK;
+}
+
+HRESULT CALLBACK ContextMenuCallback(
+ _In_opt_ IShellFolder *psf,
+ _In_opt_ HWND hwnd,
+ _In_opt_ IDataObject *pdtobj,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetUIObjectOf(
+ HWND hwndOwner,
+ UINT cidl,
+ LPCITEMIDLIST *apidl,
+ REFIID riid,
+ UINT *prgfInOut,
+ void **ppvOut)
+{
+ TRACE("GetUIObjectOf\n");
+
+ if (IsEqualIID(riid, IID_IContextMenu))
+ {
+ return ShellObjectCreatorInit<CNtObjectFolderContextMenu>(m_shellPidl,
cidl, apidl, riid, ppvOut);
+ //return CDefFolderMenu_Create2(m_shellPidl, hwndOwner, cidl, apidl, this,
ContextMenuCallback, 0, NULL, (IContextMenu**) ppvOut);
+ }
+
+ if (IsEqualIID(riid, IID_IExtractIconW))
+ {
+ return ShellObjectCreatorInit<CNtObjectFolderExtractIcon>(m_shellPidl,
cidl, apidl, riid, ppvOut);
+ }
+
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDisplayNameOf(
+ LPCITEMIDLIST pidl,
+ SHGDNF uFlags,
+ STRRET *lpName)
+{
+ NtPidlEntry * info;
+ HRESULT hr;
+
+ TRACE("GetDisplayNameOf %p\n", pidl);
+
+ hr = m_PidlManager->FindPidlInList(pidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if ((GET_SHGDN_RELATION(uFlags) == SHGDN_NORMAL) &&
+ (GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING))
+ {
+ WCHAR path[MAX_PATH] = { 0 };
+
+ hr = GetFullName(m_shellPidl, uFlags, path, _countof(path));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ PathAppendW(path, info->entryName);
+
+ hr = MakeStrRetFromString(path, lpName);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ LPCITEMIDLIST pidlNext = ILGetNext(pidl);
+
+ if (pidlNext && pidlNext->mkid.cb > 0)
+ {
+ CComPtr<IShellFolder> psfChild;
+ hr = BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ WCHAR temp[MAX_PATH];
+ STRRET childName;
+
+ hr = psfChild->GetDisplayNameOf(pidlNext, uFlags | SHGDN_INFOLDER,
&childName);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ hr = StrRetToBufW(&childName, pidlNext, temp, _countof(temp));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ PathAppendW(path, temp);
+ }
+ }
+ else
+ {
+ MakeStrRetFromString(info->entryName, info->entryNameLength, lpName);
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::SetNameOf(
+ HWND hwnd,
+ LPCITEMIDLIST pidl,
+ LPCOLESTR lpszName,
+ SHGDNF uFlags,
+ LPITEMIDLIST *ppidlOut)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+// IPersist
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetClassID(CLSID *lpClassId)
+{
+ if (!lpClassId)
+ return E_POINTER;
+
+ *lpClassId = CLSID_NtObjectFolder;
+ return S_OK;
+}
+
+// IPersistFolder
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::Initialize(LPCITEMIDLIST pidl)
+{
+ static WCHAR slash [] = L"\\";
+ return Initialize(pidl, slash);
+}
+
+// Internal
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::Initialize(LPCITEMIDLIST pidl, PWSTR ntPath)
+{
+ m_shellPidl = ILClone(pidl);
+ StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
+
+ if (!m_PidlManager)
+ m_PidlManager = new CNtObjectPidlManager();
+
+ return m_PidlManager->Initialize(m_NtPath);
+}
+
+// IPersistFolder2
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetCurFolder(LPITEMIDLIST * pidl)
+{
+ if (pidl)
+ *pidl = ILClone(m_shellPidl);
+ if (!m_shellPidl)
+ return S_FALSE;
+ return S_OK;
+}
+
+// IShellFolder2
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDefaultSearchGUID(
+ GUID *lpguid)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::EnumSearches(
+ IEnumExtraSearch **ppenum)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDefaultColumn(
+ DWORD dwReserved,
+ ULONG *pSort,
+ ULONG *pDisplay)
+{
+ if (pSort)
+ *pSort = 0;
+ if (pDisplay)
+ *pDisplay = 0;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDefaultColumnState(
+ UINT iColumn,
+ SHCOLSTATEF *pcsFlags)
+{
+ switch (iColumn)
+ {
+ case 0:
+ *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
+ return S_OK;
+ case 1:
+ *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
+ return S_OK;
+ case 2:
+ *pcsFlags = SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT;
+ return S_OK;
+ case 3:
+ *pcsFlags = SHCOLSTATE_TYPE_STR;
+ return S_OK;
+ }
+
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsEx(
+ LPCITEMIDLIST pidl,
+ const SHCOLUMNID *pscid,
+ VARIANT *pv)
+{
+ NtPidlEntry * info;
+ HRESULT hr;
+
+ TRACE("GetDetailsEx\n");
+
+ if (pidl)
+ {
+ hr = m_PidlManager->FindPidlInList(pidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ static const GUID storage = PSGUID_STORAGE;
+ if (IsEqualGUID(pscid->fmtid, storage))
+ {
+ if (pscid->pid == PID_STG_NAME)
+ {
+ return MakeVariantString(pv, info->entryName);
+ }
+ else if (pscid->pid == PID_STG_STORAGETYPE)
+ {
+ if (info->objectType < 0)
+ {
+ NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+
+ if (td->typeNameLength > 0)
+ {
+ return MakeVariantString(pv, td->typeName);
+ }
+ else
+ {
+ return MakeVariantString(pv, L"Unknown");
+ }
+ }
+ else
+ {
+ return MakeVariantString(pv, ObjectTypeNames[info->objectType]);
+ }
+ }
+ else if (pscid->pid == PID_STG_WRITETIME)
+ {
+ DOUBLE varTime;
+ SYSTEMTIME stime;
+ FileTimeToSystemTime((FILETIME*)
&(info->objectInformation.CreateTime), &stime);
+ SystemTimeToVariantTime(&stime, &varTime);
+
+ V_VT(pv) = VT_DATE;
+ V_DATE(pv) = varTime;
+ return S_OK;
+ }
+ }
+ else if (IsEqualGUID(pscid->fmtid, GUID_NtObjectColumns))
+ {
+ if (pscid->pid == PID_NTOBJECT_LINKTARGET)
+ {
+ if (info->objectType == SYMBOLICLINK_OBJECT)
+ {
+ NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+
+ if (symlink->targetNameLength > 0)
+ {
+ return MakeVariantString(pv, symlink->targetName);
+ }
+ }
+
+ return MakeVariantString(pv, L"");
+ }
+ }
+ }
+
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsOf(
+ LPCITEMIDLIST pidl,
+ UINT iColumn,
+ SHELLDETAILS *psd)
+{
+ NtPidlEntry * info;
+ HRESULT hr;
+
+ TRACE("GetDetailsOf\n");
+
+ if (pidl)
+ {
+ hr = m_PidlManager->FindPidlInList(pidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ switch (iColumn)
+ {
+ case 0:
+ psd->fmt = LVCFMT_LEFT;
+
+ MakeStrRetFromString(info->entryName, info->entryNameLength,
&(psd->str));
+ return S_OK;
+ case 1:
+ psd->fmt = LVCFMT_LEFT;
+
+ if (info->objectType < 0)
+ {
+ NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+
+ if (td->typeNameLength > 0)
+ MakeStrRetFromString(td->typeName, td->typeNameLength,
&(psd->str));
+ else
+ MakeStrRetFromString(L"Unknown", &(psd->str));
+ }
+ else
+ MakeStrRetFromString(ObjectTypeNames[info->objectType],
&(psd->str));
+ return S_OK;
+ case 2:
+ psd->fmt = LVCFMT_LEFT;
+
+ if (info->objectInformation.CreateTime.QuadPart != 0)
+ {
+ WCHAR dbuff[128];
+ PWSTR tbuff;
+ SYSTEMTIME stime;
+ FileTimeToSystemTime((LPFILETIME)
&(info->objectInformation.CreateTime), &stime);
+ GetDateFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, dbuff,
_countof(dbuff));
+ tbuff = dbuff + lstrlenW(dbuff);
+ *tbuff++ = L' ';
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, tbuff,
_countof(dbuff) - (tbuff - dbuff));
+
+ MakeStrRetFromString(dbuff, &(psd->str));
+ return S_OK;
+ }
+
+ MakeStrRetFromString(L"", &(psd->str));
+ return S_OK;
+
+ case 3:
+ psd->fmt = LVCFMT_LEFT;
+
+ if (info->objectType == SYMBOLICLINK_OBJECT)
+ {
+ NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+
+ if (symlink->targetNameLength > 0)
+ {
+ MakeStrRetFromString(symlink->targetName,
symlink->targetNameLength, &(psd->str));
+ return S_OK;
+ }
+ }
+
+ MakeStrRetFromString(L"", &(psd->str));
+ return S_OK;
+ }
+ }
+ else
+ {
+ switch (iColumn)
+ {
+ case 0:
+ psd->fmt = LVCFMT_LEFT;
+ psd->cxChar = 30;
+
+ // TODO: Make localizable
+ MakeStrRetFromString(L"Object Name", &(psd->str));
+ return S_OK;
+ case 1:
+ psd->fmt = LVCFMT_LEFT;
+ psd->cxChar = 20;
+
+ // TODO: Make localizable
+ MakeStrRetFromString(L"Object Type", &(psd->str));
+ return S_OK;
+ case 2:
+ psd->fmt = LVCFMT_LEFT;
+ psd->cxChar = 20;
+
+ // TODO: Make localizable
+ MakeStrRetFromString(L"Creation Time", &(psd->str));
+ return S_OK;
+ case 3:
+ psd->fmt = LVCFMT_LEFT;
+ psd->cxChar = 30;
+
+ // TODO: Make localizable
+ MakeStrRetFromString(L"Symlink Target", &(psd->str));
+ return S_OK;
+ }
+ }
+
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE CNtObjectFolder::MapColumnToSCID(
+ UINT iColumn,
+ SHCOLUMNID *pscid)
+{
+ static const GUID storage = PSGUID_STORAGE;
+ switch (iColumn)
+ {
+ case 0:
+ pscid->fmtid = storage;
+ pscid->pid = PID_STG_NAME;
+ return S_OK;
+ case 1:
+ pscid->fmtid = storage;
+ pscid->pid = PID_STG_STORAGETYPE;
+ return S_OK;
+ case 2:
+ pscid->fmtid = storage;
+ pscid->pid = PID_STG_WRITETIME;
+ return S_OK;
+ case 3:
+ pscid->fmtid = GUID_NtObjectColumns;
+ pscid->pid = PID_NTOBJECT_LINKTARGET;
+ return S_OK;
+ }
+ return E_FAIL;
+}
Propchange: trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/ntobjns.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjns.h (added)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjns.h [iso-8859-1] Sat Feb 21 21:21:02 2015
@@ -0,0 +1,149 @@
+/*
+ * PROJECT: ReactOS system libraries
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll\win32\stobject\stobject.cpp
+ * PURPOSE: Systray shell service object
+ * PROGRAMMERS: Robert Naumann
+ David Quintana <gigaherz(a)gmail.com>
+ */
+#pragma once
+
+extern const GUID CLSID_NtObjectFolder;
+
+class CNtObjectPidlManager;
+
+class CNtObjectFolder :
+ public CComCoClass<CNtObjectFolder, &CLSID_NtObjectFolder>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IShellFolder2,
+ public IPersistFolder2
+{
+ CNtObjectPidlManager * m_PidlManager;
+
+ WCHAR m_NtPath[MAX_PATH];
+
+ LPITEMIDLIST m_shellPidl;
+
+public:
+
+ CNtObjectFolder();
+ virtual ~CNtObjectFolder();
+
+ CNtObjectPidlManager& GetManager() { return *m_PidlManager; }
+
+ // IShellFolder
+ virtual HRESULT STDMETHODCALLTYPE ParseDisplayName(
+ HWND hwndOwner,
+ LPBC pbcReserved,
+ LPOLESTR lpszDisplayName,
+ ULONG *pchEaten,
+ LPITEMIDLIST *ppidl,
+ ULONG *pdwAttributes);
+
+ virtual HRESULT STDMETHODCALLTYPE EnumObjects(
+ HWND hwndOwner,
+ SHCONTF grfFlags,
+ IEnumIDList **ppenumIDList);
+
+ virtual HRESULT STDMETHODCALLTYPE BindToObject(
+ LPCITEMIDLIST pidl,
+ LPBC pbcReserved,
+ REFIID riid,
+ void **ppvOut);
+
+ virtual HRESULT STDMETHODCALLTYPE BindToStorage(
+ LPCITEMIDLIST pidl,
+ LPBC pbcReserved,
+ REFIID riid,
+ void **ppvObj);
+
+ virtual HRESULT STDMETHODCALLTYPE CompareIDs(
+ LPARAM lParam,
+ LPCITEMIDLIST pidl1,
+ LPCITEMIDLIST pidl2);
+
+ virtual HRESULT STDMETHODCALLTYPE CreateViewObject(
+ HWND hwndOwner,
+ REFIID riid,
+ void **ppvOut);
+
+ virtual HRESULT STDMETHODCALLTYPE GetAttributesOf(
+ UINT cidl,
+ LPCITEMIDLIST *apidl,
+ SFGAOF *rgfInOut);
+
+ virtual HRESULT STDMETHODCALLTYPE GetUIObjectOf(
+ HWND hwndOwner,
+ UINT cidl,
+ LPCITEMIDLIST *apidl,
+ REFIID riid,
+ UINT *prgfInOut,
+ void **ppvOut);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDisplayNameOf(
+ LPCITEMIDLIST pidl,
+ SHGDNF uFlags,
+ STRRET *lpName);
+
+ virtual HRESULT STDMETHODCALLTYPE SetNameOf(
+ HWND hwnd,
+ LPCITEMIDLIST pidl,
+ LPCOLESTR lpszName,
+ SHGDNF uFlags,
+ LPITEMIDLIST *ppidlOut);
+
+ // IShellFolder2
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultSearchGUID(
+ GUID *lpguid);
+
+ virtual HRESULT STDMETHODCALLTYPE EnumSearches(
+ IEnumExtraSearch **ppenum);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultColumn(
+ DWORD dwReserved,
+ ULONG *pSort,
+ ULONG *pDisplay);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultColumnState(
+ UINT iColumn,
+ SHCOLSTATEF *pcsFlags);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDetailsEx(
+ LPCITEMIDLIST pidl,
+ const SHCOLUMNID *pscid,
+ VARIANT *pv);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDetailsOf(
+ LPCITEMIDLIST pidl,
+ UINT iColumn,
+ SHELLDETAILS *psd);
+
+ virtual HRESULT STDMETHODCALLTYPE MapColumnToSCID(
+ UINT iColumn,
+ SHCOLUMNID *pscid);
+
+ // IPersist
+ virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *lpClassId);
+
+ // IPersistFolder
+ virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidl);
+
+ // IPersistFolder2
+ virtual HRESULT STDMETHODCALLTYPE GetCurFolder(LPITEMIDLIST * pidl);
+
+ // Internal
+ HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidl, PWSTR ntPath);
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_NTOBJECTFOLDER)
+ DECLARE_NOT_AGGREGATABLE(CNtObjectFolder)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CNtObjectFolder)
+ COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
+ COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
+ COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+ COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
+ COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
+ END_COM_MAP()
+
+};
Propchange: trunk/reactos/dll/shellext/ntobjshex/ntobjns.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/ntobjshex.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjshex.cpp (added)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjshex.cpp [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,74 @@
+/*
+ * PROJECT: ReactOS system libraries
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll\win32\stobject\stobject.cpp
+ * PURPOSE: COM registration services for STobject.dll
+ * PROGRAMMERS: Robert Naumann
+ David Quintana <gigaherz(a)gmail.com>
+ */
+
+#include "precomp.h"
+
+#include <atlwin.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ OBJECT_ENTRY(CLSID_NtObjectFolder, CNtObjectFolder)
+END_OBJECT_MAP()
+
+HINSTANCE g_hInstance;
+CComModule g_Module;
+
+void *operator new (size_t, void *buf)
+{
+ return buf;
+}
+
+STDAPI_(BOOL)
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hinstDLL;
+ DisableThreadLibraryCalls(g_hInstance);
+
+ /* HACK - the global constructors don't run, so I placement new them here */
+ new (&g_Module) CComModule;
+ new (&_AtlWinModule) CAtlWinModule;
+ new (&_AtlBaseModule) CAtlBaseModule;
+ new (&_AtlComModule) CAtlComModule;
+
+ g_Module.Init(ObjectMap, g_hInstance, NULL);
+ }
+ else if (fdwReason == DLL_PROCESS_DETACH)
+ {
+ g_hInstance = NULL;
+ g_Module.Term();
+ }
+ return TRUE;
+}
+
+STDAPI
+DllRegisterServer(void)
+{
+ return g_Module.DllRegisterServer(FALSE);
+}
+
+STDAPI
+DllUnregisterServer(void)
+{
+ return g_Module.DllUnregisterServer(FALSE);
+}
+
+STDAPI
+DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ return g_Module.DllGetClassObject(rclsid, riid, ppv);
+}
+
+STDAPI
+DllCanUnloadNow(void)
+{
+ return g_Module.DllCanUnloadNow();
+}
Propchange: trunk/reactos/dll/shellext/ntobjshex/ntobjshex.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/ntobjshex.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjshex.rc (added)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjshex.rc [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,23 @@
+#include <windef.h>
+#include <winuser.h>
+#include <commctrl.h>
+
+#include "resource.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+IDI_NTOBJECTFOLDER ICON "resources/1.ico"
+IDI_NTOBJECTDIR ICON "resources/2.ico"
+IDI_NTOBJECTDIROPEN ICON "resources/3.ico"
+IDI_NTOBJECTITEM ICON "resources/4.ico"
+IDI_NTOBJECTDEVICE ICON "resources/5.ico"
+IDI_NTOBJECTPORT ICON "resources/6.ico"
+
+IDR_NTOBJECTFOLDER REGISTRY "resources/rgs/ntobjectfolder.rgs"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+#ifdef LANGUAGE_EN_US
+ #include "lang/en-US.rc"
+#endif
Propchange: trunk/reactos/dll/shellext/ntobjshex/ntobjshex.rc
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/ntobjshex.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjshex.spec (added)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjshex.spec [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,4 @@
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
Propchange: trunk/reactos/dll/shellext/ntobjshex/ntobjshex.spec
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp (added)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2004, 2005 Martin Fuchs
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <precomp.h>
+
+#include "ntobjutil.h"
+#include <strsafe.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
+
+typedef NTSTATUS(__stdcall* pfnNtGenericOpen)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
+typedef NTSTATUS(__stdcall* pfnNtOpenFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG);
+
+const LPCWSTR ObjectTypeNames [] = {
+ L"Directory", L"SymbolicLink",
+ L"Mutant", L"Section", L"Event",
L"Semaphore",
+ L"Timer", L"Key", L"EventPair",
L"IoCompletion",
+ L"Device", L"File", L"Controller",
L"Profile",
+ L"Type", L"Desktop", L"WindowStatiom",
L"Driver",
+ L"Token", L"Process", L"Thread", L"Adapter",
L"Port",
+ 0
+};
+
+static DWORD NtOpenObject(OBJECT_TYPE type, HANDLE* phandle, DWORD access, LPCWSTR path)
+{
+ UNICODE_STRING ustr;
+
+ RtlInitUnicodeString(&ustr, path);
+
+ OBJECT_ATTRIBUTES open_struct = { sizeof(OBJECT_ATTRIBUTES), 0x00, &ustr, 0x40
};
+
+ if (type != FILE_OBJECT)
+ access |= STANDARD_RIGHTS_READ;
+
+ IO_STATUS_BLOCK ioStatusBlock;
+
+ switch (type)
+ {
+ case DIRECTORY_OBJECT: return NtOpenDirectoryObject(phandle, access,
&open_struct);
+ case SYMBOLICLINK_OBJECT: return NtOpenSymbolicLinkObject(phandle, access,
&open_struct);
+ case MUTANT_OBJECT: return NtOpenMutant(phandle, access, &open_struct);
+ case SECTION_OBJECT: return NtOpenSection(phandle, access, &open_struct);
+ case EVENT_OBJECT: return NtOpenEvent(phandle, access, &open_struct);
+ case SEMAPHORE_OBJECT: return NtOpenSemaphore(phandle, access,
&open_struct);
+ case TIMER_OBJECT: return NtOpenTimer(phandle, access, &open_struct);
+ case KEY_OBJECT: return NtOpenKey(phandle, access, &open_struct);
+ case EVENTPAIR_OBJECT: return NtOpenEventPair(phandle, access,
&open_struct);
+ case IOCOMPLETITION_OBJECT: return NtOpenIoCompletion(phandle, access,
&open_struct);
+ case FILE_OBJECT: return NtOpenFile(phandle, access, &open_struct,
&ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0);
+ default:
+ return ERROR_INVALID_FUNCTION;
+ }
+}
+
+OBJECT_TYPE MapTypeNameToType(LPCWSTR TypeName, DWORD cbTypeName)
+{
+ if (!TypeName)
+ return UNKNOWN_OBJECT_TYPE;
+
+ for (UINT i = 0; i < _countof(ObjectTypeNames); i++)
+ {
+ LPCWSTR typeName = ObjectTypeNames[i];
+ if (!StrCmpNW(typeName, TypeName, cbTypeName / sizeof(WCHAR)))
+ {
+ return (OBJECT_TYPE) i;
+ }
+ }
+
+ return UNKNOWN_OBJECT_TYPE;
+}
+
+HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount)
+{
+ WCHAR buffer[MAX_PATH];
+ PWSTR pend;
+
+ *hdpaCount = 0;
+
+ StringCbCopyExW(buffer, sizeof(buffer), path, &pend, NULL, 0);
+
+ ULONG enumContext = 0;
+ HANDLE directory = NULL;
+
+ DWORD err = NtOpenObject(DIRECTORY_OBJECT, &directory, FILE_LIST_DIRECTORY,
buffer);
+ if (!NT_SUCCESS(err))
+ {
+ ERR("NtOpenDirectoryObject failed for path %S with status=%x\n",
buffer, err);
+ return HRESULT_FROM_NT(err);
+ }
+
+ if (pend[-1] != '\\')
+ *pend++ = '\\';
+
+
+ BYTE dirbuffer[2048];
+
+ BOOL first = TRUE;
+ while (NtQueryDirectoryObject(directory, dirbuffer, 2048, TRUE, first,
&enumContext, NULL) == STATUS_SUCCESS)
+ {
+ first = FALSE;
+ POBJECT_DIRECTORY_INFORMATION info = (POBJECT_DIRECTORY_INFORMATION) dirbuffer;
+ //for (; info->Name.Buffer != NULL; info++)
+ {
+ if (info->Name.Buffer)
+ {
+ StringCbCopyNW(pend, sizeof(buffer), info->Name.Buffer,
info->Name.Length);
+ }
+
+ OBJECT_TYPE otype = MapTypeNameToType(info->TypeName.Buffer,
info->TypeName.Length);
+ OBJECT_BASIC_INFORMATION object = { 0 };
+
+ WCHAR wbLink[_MAX_PATH] = { 0 };
+ UNICODE_STRING link;
+ RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
+
+ DWORD entryBufferLength = sizeof(NtPidlEntry) + sizeof(WCHAR);
+ if (info->Name.Buffer)
+ entryBufferLength += info->Name.Length;
+
+ if (otype < 0)
+ {
+ entryBufferLength += sizeof(NtPidlTypeData) + sizeof(WCHAR);
+
+ if (info->TypeName.Buffer)
+ {
+ entryBufferLength += info->TypeName.Length;
+ }
+ }
+
+ if (otype == SYMBOLICLINK_OBJECT)
+ {
+ entryBufferLength += sizeof(NtPidlSymlinkData) + sizeof(WCHAR);
+ }
+
+ DWORD access = STANDARD_RIGHTS_READ;
+ if ((otype == DIRECTORY_OBJECT) ||
+ (otype == SYMBOLICLINK_OBJECT))
+ access |= FILE_LIST_DIRECTORY;
+
+ HANDLE handle;
+ if (!NtOpenObject(otype, &handle, access, buffer))
+ {
+ DWORD read;
+
+ if (!NT_SUCCESS(NtQueryObject(handle, ObjectBasicInformation,
&object, sizeof(OBJECT_BASIC_INFORMATION), &read)))
+ {
+ ZeroMemory(&object, sizeof(OBJECT_BASIC_INFORMATION));
+ }
+
+ if (otype == SYMBOLICLINK_OBJECT)
+ {
+ if (NtQuerySymbolicLinkObject(handle, &link, NULL) ==
STATUS_SUCCESS)
+ {
+ entryBufferLength += link.Length;
+ }
+ else
+ {
+ link.Length = 0;
+ }
+ }
+
+ NtClose(handle);
+ }
+
+ NtPidlEntry* entry = (NtPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+ if (!entry)
+ return E_OUTOFMEMORY;
+
+ memset(entry, 0, entryBufferLength);
+
+ entry->cb = sizeof(NtPidlEntry);
+ entry->magic = NT_OBJECT_PIDL_MAGIC;
+ entry->objectType = otype;
+ entry->objectInformation = object;
+ memset(entry->objectInformation.Reserved, 0,
sizeof(entry->objectInformation.Reserved));
+
+ if (info->Name.Buffer)
+ {
+ entry->entryNameLength = info->Name.Length;
+ StringCbCopyNW(entry->entryName, entryBufferLength,
info->Name.Buffer, info->Name.Length);
+ entry->cb += entry->entryNameLength + sizeof(WCHAR);
+ }
+ else
+ {
+ entry->entryNameLength = 0;
+ entry->entryName[0] = 0;
+ entry->cb += sizeof(WCHAR);
+ }
+
+ if (otype < 0)
+ {
+ NtPidlTypeData * typedata = (NtPidlTypeData*) ((PBYTE) entry +
entry->cb);
+ DWORD remainingSpace = entryBufferLength - ((PBYTE)
(typedata->typeName) - (PBYTE) entry);
+
+ if (info->TypeName.Buffer)
+ {
+ typedata->typeNameLength = info->TypeName.Length;
+ StringCbCopyNW(typedata->typeName, remainingSpace,
info->TypeName.Buffer, info->TypeName.Length);
+
+ entry->cb += typedata->typeNameLength + sizeof(WCHAR);
+ }
+ else
+ {
+ typedata->typeNameLength = 0;
+ typedata->typeName[0] = 0;
+ entry->cb += typedata->typeNameLength + sizeof(WCHAR);
+ }
+ }
+
+ if (otype == SYMBOLICLINK_OBJECT)
+ {
+ NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) ((PBYTE) entry +
entry->cb);
+ DWORD remainingSpace = entryBufferLength - ((PBYTE)
(symlink->targetName) - (PBYTE) entry);
+
+ symlink->targetNameLength = link.Length;
+ StringCbCopyNW(symlink->targetName, remainingSpace, link.Buffer,
link.Length);
+
+ entry->cb += symlink->targetNameLength + sizeof(WCHAR);
+ }
+
+ DPA_AppendPtr(hdpa, entry);
+ (*hdpaCount)++;
+ }
+ }
+
+ NtClose(directory);
+
+ return S_OK;
+}
Propchange: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h (added)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h [iso-8859-1] Sat Feb 21 21:21:02
2015
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004 Martin Fuchs
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+extern "C" {
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+#include <ndk/rtlfuncs.h>
+}
+
+// All the possible values are defined here because I want the type field to be
+// "persistable" and not change if more types are added in the future.
+enum OBJECT_TYPE {
+ DIRECTORY_OBJECT, SYMBOLICLINK_OBJECT,
+ MUTANT_OBJECT, SECTION_OBJECT, EVENT_OBJECT, SEMAPHORE_OBJECT,
+ TIMER_OBJECT, KEY_OBJECT, EVENTPAIR_OBJECT, IOCOMPLETITION_OBJECT,
+ DEVICE_OBJECT, FILE_OBJECT, CONTROLLER_OBJECT, PROFILE_OBJECT,
+ TYPE_OBJECT, DESKTOP_OBJECT, WINDOWSTATION_OBJECT, DRIVER_OBJECT,
+ TOKEN_OBJECT, PROCESS_OBJECT, THREAD_OBJECT, ADAPTER_OBJECT, PORT_OBJECT,
+
+ UNKNOWN_OBJECT_TYPE = -1
+};
+extern const LPCWSTR ObjectTypeNames [];
+
+#define NT_OBJECT_PIDL_MAGIC (USHORT)0x9A03
+
+#include <pshpack1.h>
+struct NtPidlEntry
+{
+ SHORT cb;
+ USHORT magic; // 0x9A03 ~~~ "NTOB"
+
+ // If this is -1, there will be a NtPidlTypeData following this, and before any other
extensions
+ OBJECT_TYPE objectType;
+
+ OBJECT_BASIC_INFORMATION objectInformation;
+
+ USHORT entryNameLength;
+ WCHAR entryName[0];
+
+};
+
+struct NtPidlTypeData
+{
+ USHORT typeNameLength;
+ WCHAR typeName[0];
+};
+
+struct NtPidlSymlinkData
+{
+ USHORT targetNameLength;
+ WCHAR targetName[0];
+};
+#include <poppack.h>
+
+HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount);
Propchange: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/precomp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/pre…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/precomp.h (added)
+++ trunk/reactos/dll/shellext/ntobjshex/precomp.h [iso-8859-1] Sat Feb 21 21:21:02 2015
@@ -0,0 +1,49 @@
+#pragma once
+
+#define WIN32_NO_STATUS
+#include <stdarg.h>
+#include <tchar.h>
+
+#define COBJMACROS
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+#define NTOS_MODE_USER
+
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <winuser.h>
+#include <wincon.h>
+#include <ddeml.h>
+#include <shlguid_undoc.h>
+#include <shlwapi.h>
+#include <shlobj.h>
+#include <shlobj_undoc.h>
+#include <shlwapi_undoc.h>
+#include <tchar.h>
+#include <strsafe.h>
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlwin.h>
+#include <undocshell.h>
+#include <shellutils.h>
+
+#include <shellapi.h>
+
+#include <wine/debug.h>
+#include <wine/unicode.h>
+
+#include "resource.h"
+
+#undef DbgPrint
+
+extern HINSTANCE g_hInstance;
+
+#define ID_ICON_VOLUME (WM_APP + 0x4CB)
+
+// {845B0FB2-66E0-416B-8F91-314E23F7C12D}
+DEFINE_GUID(CLSID_NtObjectFolder,
+ 0x845b0fb2, 0x66e0, 0x416b, 0x8f, 0x91, 0x31, 0x4e, 0x23, 0xf7, 0xc1, 0x2d);
+
+#include "ntobjns.h"
Propchange: trunk/reactos/dll/shellext/ntobjshex/precomp.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/shellext/ntobjshex/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/resource.h (added)
+++ trunk/reactos/dll/shellext/ntobjshex/resource.h [iso-8859-1] Sat Feb 21 21:21:02 2015
@@ -0,0 +1,12 @@
+#pragma once
+
+#define IDI_NTOBJECTFOLDER 1
+#define IDI_NTOBJECTDIR 2
+#define IDI_NTOBJECTDIROPEN 3
+#define IDI_NTOBJECTITEM 4
+#define IDI_NTOBJECTDEVICE 5
+#define IDI_NTOBJECTPORT 6
+
+#define IDS_NAME 101
+
+#define IDR_NTOBJECTFOLDER 1001
Propchange: trunk/reactos/dll/shellext/ntobjshex/resource.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Sat Feb 21 21:21:02 2015
@@ -0,0 +1 @@
+((CORE|ROSTESTS|ROSAPPS)-\d+)(,? ?((CORE|ROSTESTS|ROSAPPS)-\d+))*(,? ?(and |or
)?((CORE|ROSTESTS|ROSAPPS)-\d+))?
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/
------------------------------------------------------------------------------
bugtraq:message = See issue %BUGID% for more details.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/
------------------------------------------------------------------------------
bugtraq:url =
https://jira.reactos.org/browse/%BUGID%
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/dll/shellext/ntobjshex/resources/1.ico
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
Binary file - no diff available.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/1.ico
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: trunk/reactos/dll/shellext/ntobjshex/resources/2.ico
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
Binary file - no diff available.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/2.ico
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: trunk/reactos/dll/shellext/ntobjshex/resources/3.ico
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
Binary file - no diff available.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/3.ico
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: trunk/reactos/dll/shellext/ntobjshex/resources/4.ico
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
Binary file - no diff available.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/4.ico
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: trunk/reactos/dll/shellext/ntobjshex/resources/5.ico
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
Binary file - no diff available.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/5.ico
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: trunk/reactos/dll/shellext/ntobjshex/resources/6.ico
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
Binary file - no diff available.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/6.ico
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/rgs/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Sat Feb 21 21:21:02 2015
@@ -0,0 +1 @@
+((CORE|ROSTESTS|ROSAPPS)-\d+)(,? ?((CORE|ROSTESTS|ROSAPPS)-\d+))*(,? ?(and |or
)?((CORE|ROSTESTS|ROSAPPS)-\d+))?
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/rgs/
------------------------------------------------------------------------------
bugtraq:message = See issue %BUGID% for more details.
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/rgs/
------------------------------------------------------------------------------
bugtraq:url =
https://jira.reactos.org/browse/%BUGID%
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/rgs/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/dll/shellext/ntobjshex/resources/rgs/ntobjectfolder.rgs
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/resources/rgs/ntobjectfolder.rgs (added)
+++ trunk/reactos/dll/shellext/ntobjshex/resources/rgs/ntobjectfolder.rgs [iso-8859-1] Sat
Feb 21 21:21:02 2015
@@ -0,0 +1,47 @@
+HKCR
+{
+ NoRemove CLSID
+ {
+ ForceRemove {845B0FB2-66E0-416B-8F91-314E23F7C12D} = s 'NT Object Namespace
Extension'
+ {
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Both'
+ }
+ val InfoTip = s 'Allows browsing of the NT Object Namespace'
+ DefaultIcon = s '%MODULE%,0'
+ ShellFolder
+ {
+ val Attributes = d '0xA8000000'
+ val BrowserFlags = d '0x22'
+ }
+ }
+ }
+}
+HKLM
+{
+ NoRemove Software
+ {
+ NoRemove Microsoft
+ {
+ NoRemove Windows
+ {
+ NoRemove CurrentVersion
+ {
+ NoRemove Explorer
+ {
+ NoRemove MyComputer
+ {
+ NoRemove NameSpace
+ {
+ ForceRemove {845B0FB2-66E0-416B-8F91-314E23F7C12D} = s 'NT Object
Namespace Extension'
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
Propchange: trunk/reactos/dll/shellext/ntobjshex/resources/rgs/ntobjectfolder.rgs
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/include/reactos/shellutils.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/shellutils…
==============================================================================
--- trunk/reactos/include/reactos/shellutils.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/shellutils.h [iso-8859-1] Sat Feb 21 21:21:02 2015
@@ -32,7 +32,7 @@
#endif
#if 1
-#define FAILED_UNEXPECTEDLY(hr) (FAILED(hr) && (DbgPrint("Unexpected failure
%08x.\n", hr), TRUE))
+#define FAILED_UNEXPECTEDLY(hr) (FAILED(hr) && (Win32DbgPrint(__FILE__, __LINE__,
"Unexpected failure %08x.\n", hr), TRUE))
#else
#define FAILED_UNEXPECTEDLY(hr) FAILED(hr)
#endif
@@ -263,6 +263,52 @@
return S_OK;
}
+template<class T, class T1, class T2>
+HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, void **
ppv)
+{
+ CComPtr<T> obj;
+ HRESULT hResult;
+
+ if (ppv == NULL)
+ return E_POINTER;
+ *ppv = NULL;
+ ATLTRY(obj = new _CComObject<T>);
+ if (obj.p == NULL)
+ return E_OUTOFMEMORY;
+ hResult = obj->QueryInterface(riid, ppv);
+ if (FAILED(hResult))
+ return hResult;
+
+ hResult = obj->Initialize(initArg1, initArg2);
+ if (FAILED(hResult))
+ return hResult;
+
+ return S_OK;
+}
+
+template<class T, class T1, class T2, class T3>
+HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REFIID riid,
void ** ppv)
+{
+ CComPtr<T> obj;
+ HRESULT hResult;
+
+ if (ppv == NULL)
+ return E_POINTER;
+ *ppv = NULL;
+ ATLTRY(obj = new _CComObject<T>);
+ if (obj.p == NULL)
+ return E_OUTOFMEMORY;
+ hResult = obj->QueryInterface(riid, ppv);
+ if (FAILED(hResult))
+ return hResult;
+
+ hResult = obj->Initialize(initArg1, initArg2, initArg3);
+ if (FAILED(hResult))
+ return hResult;
+
+ return S_OK;
+}
+
template<class T, class T1, class R>
HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, R ** ppv)
{