Re[3]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 20.11.13 06:21
Оценка: +1
Здравствуйте, M3fN, Вы писали:

MN>format.cfFormat=-16147 (49388) — DropEffectFolderList

MN>format.cfFormat=-16244 (49291) — C:\Windows\system32\WINMM.dll
MN>format.cfFormat=15 (15) — "FmtName returned zero" — C:\Windows\system32\WINMM.dll

Я бы использовал иную математику

-16147 = C0ED = 49389
-16244 = C08C = 49292
Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 19.11.13 14:05
Оценка:
Доброго времени суток.
Имею дело с windows-only приложением на c#/.net 4.0. Успешно интегрировал IExplorerBrowser в приложение (благо WindowsAPICodecPack есть, хоть и доработать пришлось немного).

Теперь есть задача сделать так, чтобы этим-же IExplorerBrowser можно было ходить по FTP.
Кто хочет сразу прочитать суть вопроса — прошу пропустить следующий код.
Вот что я сделал изначально для решения этой задачи (код пока сваливал почти в кучу ибо долго в этом всем разбирался).

explorerBrowserControl — инстанс IExplorerBrowser ("71F96385-DDD6-48D3-A0C1-AE06E8B055FB")

... // OnCreateControl
explorerBrowserControl = new ExplorerBrowserClass();

ExplorerBrowserNativeMethods.IUnknown_SetSite(explorerBrowserControl, this);

explorerBrowserControl.Advise(
    Marshal.GetComInterfaceForObject(this, typeof(IExplorerBrowserEvents)),
    out eventsCookie);

viewEvents = new ExplorerBrowserViewEvents(this);

NativeRect rect = new NativeRect();
rect.Top = ClientRectangle.Top;
rect.Left = ClientRectangle.Left;
rect.Right = ClientRectangle.Right;
rect.Bottom = ClientRectangle.Bottom;

FolderSettings fs = new FolderSettings();
fs.ViewMode = FolderViewMode.Details;
fs.Options = FolderOptions.AutoArrange | FolderOptions.NoWebView;

explorerBrowserControl.Initialize(this.Handle, ref rect, null);
explorerBrowserControl.SetOptions(ExplorerBrowserOptions.AlwaysNavigate);

explorerBrowserControl.FillFromObject(IntPtr.Zero, 0x00); // HERE

... //

[ComVisible(true)]
[Guid("618C54EC-1C73-4CF1-878F-89F46589C5DA")]
[ClassInterface(ClassInterfaceType.None)]
    [ProgId("Microsoft.WindowsAPICodePack.Shell.Custom.FtpSourceShellItem")]
    [ComSourceInterfaces(typeof(IShellItem2))]
    public class FtpSourceShellItem : IShellItem2

... // При создании айтема ftpSource.

Type shellType = Type.GetTypeFromCLSID(new Guid("618C54EC-1C73-4CF1-878F-89F46589C5DA"), true); 
object shel = Activator.CreateInstance(shellType);
newItem = shell as IShellItem2;

if (hr != HResult.Ok)
{
    throw new ShellException("Could not create ftp shell item", hr);
}

ftpSource.nativeShellItem = newItem;

... // Метод Navigate, в тестовых целях вызывается раз.

explorerBrowserControl.SetOptions(ExplorerBrowserOptions.NavigateOnce);

IntPtr temp;
Guid iid = new Guid(ExplorerBrowserIIDGuid.IFolderView2);
HResult result = explorerBrowserControl.GetCurrentView(ref iid, out temp);
                    
if (result != HResult.Ok)
{
    throw new ShellException("Failed calling IExplorerBrowser.GetCurrentView(ref Guid, out IFolderView2)", result);
}

IFolderView2 ifv2 = (IFolderView2)Marshal.GetObjectForIUnknown(temp);
IResultsFolder prf;
object temp2;
                    
iid = new Guid(ExplorerBrowserIIDGuid.IResultsFolder);
result = ifv2.GetFolder(ref iid, out prf);

if (result != HResult.Ok)
{
    throw new ShellException("Failed calling IFolderView2.GetFolder(ref Guid, out IResultsFolder)", result);
}

prf.AddItem(ftpSource.nativeShellItem);


Но таким способом нельзя описывать сам item, и методы его не вызываются вовсе. Может как-то и можно его описать и не городить то, что приведено ниже.
Решил реализовать IDataObject для метода IExplorerBrowser.FillFromObject, чтобы информация про айтемы бралась оттуда.

[ComVisible(true)]
[Guid("1BE34910-108C-4A61-B4CA-9B6F87815607")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Microsoft.WindowsAPICodePack.Shell.Custom.DataSource")]
[ComSourceInterfaces(typeof(IDataObject))]
public class DataObject : IDataObject
{
    public void GetData(ref FORMATETC format, out STGMEDIUM medium)
    {
        Console.WriteLine("GetData");
        Console.WriteLine(
            "format.cfFormat: " + format.cfFormat + 
            " format.dwAspect:" + format.dwAspect +
            " format.lindex:" + format.lindex + 
            " format.ptd:" + format.ptd +
            " format.tymed:" + format.tymed
            );

            medium = new STGMEDIUM();
            medium.tymed = TYMED.TYMED_HGLOBAL;
    }
    ... // Далее примерно так же
}

... //OnCreateControl
...

Type shellType = Type.GetTypeFromCLSID(new Guid("1BE34910-108C-4A61-B4CA-9B6F87815607"), true);
object shell = Activator.CreateInstance(shellType);

HResult result = explorerBrowserControl.FillFromObject(shell, 0x00);


После вызова FillFromObject вызывается только метод GetData, три раза со следующими параметрами:
— format.cfFormat=-16147, format.dwAspect=DVASPECT_CONTENT, format.lindex=-1, format.ptd=0, format.tymed=TYMED_HGLOBAL
— format.cfFormat=-16244, format.dwAspect=DVASPECT_CONTENT, format.lindex=-1, format.ptd=0, format.tymed=TYMED_HGLOBAL
— format.cfFormat=15, format.dwAspect=DVASPECT_CONTENT, format.lindex=-1, format.ptd=0, format.tymed=TYMED_HGLOBAL

Иногда появляется зелёный иероглиф возле иконки пустого файла.
Собственно основной вопрос здесь — куда дальше двигаться?

15 это, согласно документации — CF_HDROP, что не имеет, как по мне, смысла.
По остальным значениям ничего в интернете нет.
Если искать их с учётом того что это скорее всего выход за пределы ushort.MaxValue — гугл выдаёт авиабазы и сайты на китайском от безысходности.
Re: Заголовок должен быть: Custom Items для IExplorerBrowser
От: M3fN  
Дата: 19.11.13 14:07
Оценка:
Re: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 20.11.13 03:11
Оценка:
MN>15 это, согласно документации — CF_HDROP, что не имеет, как по мне, смысла.

Почему не имеет. Еще как имеет.

MN>По остальным значениям ничего в интернете нет.


Для остальных значений вызови GetClipboardFormatName и отпишись о результатах.
Re[2]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 20.11.13 05:31
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Для остальных значений вызови GetClipboardFormatName и отпишись о результатах.


Надеюсь я правильно перевёл overflow short в usingned int

Console.WriteLine("GetData");
Console.WriteLine(
    "format.cfFormat: " + format.cfFormat + 
    " format.dwAspect:" + format.dwAspect +
    " format.lindex:" + format.lindex + 
    " format.ptd:" + format.ptd +
    " format.tymed:" + format.tymed
    );

StringBuilder cName = new StringBuilder(255);

uint bits = (uint) (format.cfFormat >= 0 ? format.cfFormat : Math.Abs((-format.cfFormat) + Int16.MinValue) + Int16.MaxValue);

Console.WriteLine(bits);

if (GetClipboardFormatName(bits, cName, 255) == 0)
{
    Console.WriteLine("FmtName returned zero");
}

Console.WriteLine(cName.ToString());


format.cfFormat=-16147 (49388) — DropEffectFolderList
format.cfFormat=-16244 (49291) — C:\Windows\system32\WINMM.dll
format.cfFormat=15 (15) — "FmtName returned zero" — C:\Windows\system32\WINMM.dll

Если просто убрать минус у cfFormat — функция не проходит так же как и с cfFormat=15

Куда двигаться дальше так и не знаю , такое ощущение что я тут первопроходец, хоть и имею дело с COM впервые.
Re[4]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 20.11.13 09:12
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Я бы использовал иную математику


A>-16147 = C0ED = 49389

A>-16244 = C08C = 49292

Спасибо. Теперь GetClipboardFormatName выдаёт "Autoplay Enumerated IDlist array" и "Shell IDlist array".
Где можно почитать по этим форматам?
Re[5]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 20.11.13 09:27
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>Теперь GetClipboardFormatName выдаёт "Autoplay Enumerated IDlist array" и "Shell IDlist array".

MN>Где можно почитать по этим форматам?

http://msdn.microsoft.com/en-us/library/windows/desktop/bb776902%28v=vs.85%29.aspx#CFSTR_SHELLIDLIST

Autoplay Enumerated IDlist array — это тоже самое, что "Shell IDlist array", но просто с другим ID.
Re[5]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 20.11.13 09:34
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>Здравствуйте, Aniskin, Вы писали:


A>>Я бы использовал иную математику


A>>-16147 = C0ED = 49389

A>>-16244 = C08C = 49292

MN>Спасибо. Теперь GetClipboardFormatName выдаёт "Autoplay Enumerated IDlist array" и "Shell IDlist array".

MN>Где можно почитать по этим форматам?

Кое-что нагуглил, внезпно, на народ.ру
http://win-api.narod.ru/a0006.htm
http://win-api.narod.ru/a0651.htm

Пока копаю дальше, в этот COM.
Re[6]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 20.11.13 11:59
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>Пока копаю дальше, в этот COM.


Предполагаю, что придется тебе писать namespace shell extension, а уже его отображать в IExplorerBrowser.
Re[6]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 20.11.13 12:21
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>http://msdn.microsoft.com/en-us/library/windows/desktop/bb776902%28v=vs.85%29.aspx#CFSTR_SHELLIDLIST


A>Autoplay Enumerated IDlist array — это тоже самое, что "Shell IDlist array", но просто с другим ID.


Для отладки вынес функционал в другой класс.
Сейчас делаю так:

        public static class Util
    {
        public static uint OverflowShortToUInt(short s)
        {
            return (uint)(s >= 0 ? s : Math.Abs((-s) + Int16.MinValue) + Int16.MaxValue + 1);
        }
    }
        unsafe public class DataObjectS
        {
            public static DataObject.CIDA cida;
            public static IntPtr ciPtr;

            [DllImport("ntdll.dll")]
            public static extern int memcpy(int dst, int src, int count);

        static DataObjectS()
        {
            IntPtr idList = ShellNativeMethods.SHSimpleIDListFromPath("ftp://smth.com");
            IntPtr idListFile = ShellNativeMethods.SHSimpleIDListFromPath("ftp://smth.com/hi");

            DataObject.ITEMIDLIST idListS = (DataObject.ITEMIDLIST)Marshal.PtrToStructure(idList, typeof(DataObject.ITEMIDLIST));
            DataObject.ITEMIDLIST idListFileS = (DataObject.ITEMIDLIST)Marshal.PtrToStructure(idListFile, typeof(DataObject.ITEMIDLIST));

            int itemDListSize = idListFileS.mkid.cb; //both item`s size is equal

            // CIDA size + second element of uint[] + 2 ITEMIDLIST
            ciPtr = Marshal.AllocHGlobal(sizeof(DataObject.CIDA) + sizeof(uint) + itemDListSize * 2);

            cida = (DataObject.CIDA)Marshal.PtrToStructure(ciPtr, typeof(DataObject.CIDA));
            cida.cidl = 2;

            fixed (uint* cidaAOffs = cida.aoffset)
            {
                cidaAOffs[0] = (uint)(sizeof(DataObject.CIDA) + sizeof(uint));
                cidaAOffs[1] = (uint)(sizeof(DataObject.CIDA) + sizeof(uint) + itemDListSize);

                memcpy((int) (ciPtr.ToInt32() + cidaAOffs[0]), idList.ToInt32(), itemDListSize);
                memcpy((int) (ciPtr.ToInt32() + cidaAOffs[1]), idListFile.ToInt32(), itemDListSize);

                // Check on debug.
                IntPtr ptr = new IntPtr(ciPtr.ToInt32() + cidaAOffs[1]);
                                // Тут не сходится
                DataObject.ITEMIDLIST idListFileSCheck = (DataObject.ITEMIDLIST)Marshal.PtrToStructure(ptr, typeof(DataObject.ITEMIDLIST)); 
            }
        }
                // Вызывается перед всем остальным
        public static void ChopChop() // COM-object cannot be debugged and does not call static constructor
        {
            
        }
    }

    [ComVisible(true)]
    [Guid("1BE34910-108C-4A61-B4CA-9B6F87815607")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("Microsoft.WindowsAPICodePack.Shell.Custom.DataSource")]
    [ComSourceInterfaces(typeof(IDataObject))]
    unsafe public class DataObject : IDataObject
    {
        enum CFormat
        {
            CF_TEXT = 1,
            CF_BITMAP = 2,
            CF_METAFILEPICT = 3,
            CF_SYLK = 4,
            CF_DIF = 5,
            CF_TIFF = 6,
            CF_OEMTEXT = 7,
            CF_DIB = 8,
            CF_PALETTE = 9,
            CF_PENDATA = 10,
            CF_RIFF = 11,
            CF_WAVE = 12,
            CF_UNICODETEXT = 13,
            CF_ENHMETAFILE = 14,
            // For windows XP+
            CF_HDROP = 15,
            CF_LOCALE = 16,
            CF_DIBV5 = 17,
            CF_MAX = 18,
            CF_OWNERDISPLAY = 0x0080,
            CF_DSPTEXT = 0x0081,
            CF_DSPBITMAP = 0x0082,
            CF_DSPMETAFILEPICT = 0x0083,
            CF_DSPENHMETAFILE = 0x008E,
            /*
             * "Private" formats don't get GlobalFree()'d
             */
            CF_PRIVATEFIRST = 0x0200,
            CF_PRIVATELAST = 0x02FF,
            /*
             * "GDIOBJ" formats do get DeleteObject()'d
             */
            CF_GDIOBJFIRST = 0x0300,
            CF_GDIOBJLAST = 0x03FF,
            /*
             * Situatuion-related
             */
            FC_AutoplayEnumIDListArray = 0xC0ED,
            FC_ShellIDListArray = 0xC08C
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CIDA 
        {
            public uint cidl;
            public fixed uint aoffset[1]; // list of ITEMIDLIST
        };

        [StructLayout(LayoutKind.Sequential)]
        public struct ITEMIDLIST 
        {
            public SHITEMID mkid;
        };

        [StructLayout(LayoutKind.Sequential)]
        public struct SHITEMID 
        {
            public ushort cb;
            public byte[1] abID; // list of ?
        };

        public void GetData(ref FORMATETC format, out STGMEDIUM medium)
        {
            Console.WriteLine("GetData");
            Console.WriteLine(
                "format.cfFormat: " + format.cfFormat + 
                " format.dwAspect:" + format.dwAspect +
                " format.lindex:" + format.lindex + 
                " format.ptd:" + format.ptd +
                " format.tymed:" + format.tymed
                );

            uint cFormat = Util.OverflowShortToUInt(format.cfFormat);

            Console.WriteLine(cFormat);

            /*StringBuilder cName = new StringBuilder(255);

            if (GetClipboardFormatName(bits, cName, 255) == 0)
            {
                Console.WriteLine("FmtName returned zeo");
            }

            Console.WriteLine(cName.ToString());*/

            medium = new STGMEDIUM();

            if ((CFormat)cFormat  == CFormat.FC_ShellIDListArray)
            {
                medium.unionmember = DataObjectS.ciPtr;
            }
        }
    .......


Если я правильно понимаю — если я хочу всё сделать сплошным куском (все offsets рядом) — для двух айтемов нужно выделить sizeof(DataObject.CIDA) + (sizeof(uint)*(2-1)) + размер ITEMIDLIST * (2)
Так как CIDA содержит массив с 1 элементом, а нужно 2 — выделяем ещё плюс sizeof(uint), и плюс 2 объекта ITEMIDLIST.

В вышеприведённом коде в методе DataObjectS() почему-то не сходятся значения структур (обычно отличаются на 1-2 последних цифры).

Сейчас код падает с ошибкой Access violation reading location, с адресом, никак не связаным ни с CIDA, ни с содержимым ITEMIDLIST (а там тоже невалидная ссылка) полученным через SHSimpleIDListFromPath с несуществующим адресом.

Тяжело однако.
Re[7]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 20.11.13 12:27
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Здравствуйте, M3fN, Вы писали:


MN>>Пока копаю дальше, в этот COM.


A>Предполагаю, что придется тебе писать namespace shell extension, а уже его отображать в IExplorerBrowser.


Через реализацию IDataObject это вообще можно сделать? А то я просто копаю, не знаю куда. Если да, то как будет легче и быстрее?
Уже уйму времени потратил с начала недели. Такое ощущение что в COM всё сделано максимально сложно.
Re[7]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 20.11.13 13:48
Оценка:
Здравствуйте, M3fN, Вы писали:

В код не вникал, поскольку не знакомый мне ЯП.

MN> FC_AutoplayEnumIDListArray = 0xC0ED,

MN> FC_ShellIDListArray = 0xC08C

Эти величины должны получаться путем вызова RegisterClipboardFormat с "Autoplay Enumerated IDlist array" и "Shell IDlist array" соответственно.

MN>Если я правильно понимаю — если я хочу всё сделать сплошным куском (все offsets рядом) — для двух айтемов нужно выделить sizeof(DataObject.CIDA) + (sizeof(uint)*(2-1)) + размер ITEMIDLIST * (2)

MN>Так как CIDA содержит массив с 1 элементом, а нужно 2 — выделяем ещё плюс sizeof(uint), и плюс 2 объекта ITEMIDLIST.

Для N элементов нужно выделить sizeof(UINT {CIDA.cidl}) + sizeof(UINT) * (N + 1) + sizeof(ITEMIDLIST) * (N + 1) байт.

MN>Сейчас код падает с ошибкой Access violation reading location, с адресом, никак не связаным ни с CIDA, ни с содержимым ITEMIDLIST (а там тоже невалидная ссылка) полученным через SHSimpleIDListFromPath с несуществующим адресом.


Я думаю проблема в том, что после получения твоих структур IExplorerBrowser начинает вызывать различные функции для работы с ITEMIDLIST, и при этом подразумевается, что твои ITEMIDLIST-ты ссылаются на какие-либо реально существующие объекты реальной или виртуальной файловой системы. А поскольку их нет, то и возникают AV. Поэтому я и написал, что нужно писать namespace shell extension, тогда у shell32.dll к тебе претензий в виде AV не будет.
Re[8]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 20.11.13 13:56
Оценка:
Здравствуйте, M3fN, Вы писали:

A>>Предполагаю, что придется тебе писать namespace shell extension, а уже его отображать в IExplorerBrowser.


MN>Через реализацию IDataObject это вообще можно сделать?


Нет. Namespace shell extension — это отдельная dll, регистрируемая в системе. Подробнее.

MN>А то я просто копаю, не знаю куда. Если да, то как будет легче и быстрее?


Если стоит задача отображать в IExplorerBrowser произвольные данные, то imho он для этого не предназначен. Поэтому нужно/можно использовать обходной путь в виде namespace shell extension. Конечно, возможно, что я и ошибаюсь.

MN>Такое ощущение что в COM всё сделано максимально сложно.


Я тоже по началу так думал. С тех под прошло много лет. И мое мнение совершенно не изменилось
Re[8]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 20.11.13 14:32
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Я думаю проблема в том, что после получения твоих структур IExplorerBrowser начинает вызывать различные функции для работы с ITEMIDLIST, и при этом подразумевается, что твои ITEMIDLIST-ты ссылаются на какие-либо реально существующие объекты реальной или виртуальной файловой системы. А поскольку их нет, то и возникают AV. Поэтому я и написал, что нужно писать namespace shell extension, тогда у shell32.dll к тебе претензий в виде AV не будет.


ITEMIDLIST может быть "провайдером" только для объектов виртуальной или реальной файловой системы? Ничего кастомного туда нельзя запихнуть?
Например, реализовать IShellItem2 и каким-то образом сказать ITEMIDLIST ссылаться на него?
Re[9]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 20.11.13 16:35
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>ITEMIDLIST может быть "провайдером" только для объектов виртуальной или реальной файловой системы?


Imho, да.

Ничего кастомного туда нельзя запихнуть?

Imho, нельзя.

MN>Например, реализовать IShellItem2 и каким-то образом сказать ITEMIDLIST ссылаться на него?


Я такого пути не знаю.

ITEMIDLIST — это просто набор байтов, о сути которых знает только та сущность, что их создала. Shell оперирует этими ITEMIDLIST без понимания, что в них находятся. Если нужно получить имя объекта, то shell просто обращается к IShellFolder2, который реализует расширение оболочки.
Re[7]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 21.11.13 07:09
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Здравствуйте, M3fN, Вы писали:


MN>>Пока копаю дальше, в этот COM.


A>Предполагаю, что придется тебе писать namespace shell extension, а уже его отображать в IExplorerBrowser.


Прочел http://www.codeproject.com/Articles/1649/The-Complete-Idiot-s-Guide-to-Writing-Namespace-Ex?fid=3003&df=90&mpp=25&noise=3&prof=False&sort=Position&view=Quick&spc=Relaxed&fr=26#xx0xx
но так и не понял как теперь это использовать. Как? В IExplorerBrowser желательно.
Re[8]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 21.11.13 07:31
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>но так и не понял как теперь это использовать. Как? В IExplorerBrowser желательно.


В namespace extension реализуется логика получения имен файлов, которые нужно отображать в IExplorerBrowser, т.е. реализуется виртуальные файлы. А затем в IExplorerBrowser через IDataObject передаются ссылки на эти виртуальные файлы. После чего IExplorerBrowser спокойно отображает эти самые виртуальные файлы. Как-то так.
Re[9]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 21.11.13 07:40
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Здравствуйте, M3fN, Вы писали:


MN>>но так и не понял как теперь это использовать. Как? В IExplorerBrowser желательно.


A>В namespace extension реализуется логика получения имен файлов, которые нужно отображать в IExplorerBrowser, т.е. реализуется виртуальные файлы. А затем в IExplorerBrowser через IDataObject передаются ссылки на эти виртуальные файлы. После чего IExplorerBrowser спокойно отображает эти самые виртуальные файлы. Как-то так.


Есть зарегистрированные классы:

class ATL_NO_VTABLE CShellViewImpl : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CShellViewImpl, &CLSID_ShellViewImpl>,
    public IShellView,
    public IOleCommandTarget,
    public CWindowImpl<CShellViewImpl>

class ATL_NO_VTABLE CShellFolderImpl : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CShellFolderImpl, &CLSID_ShellFolderImpl>,
    public IShellFolder,
    public IPersistFolder


Как их теперь использовать для получения виртуальных id? Google "Using namespace shell extension" выдаёт ничего.
Re[10]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 21.11.13 08:00
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>Как их теперь использовать для получения виртуальных id? Google "Using namespace shell extension" выдаёт ничего.


Я думаю, что стоит начать с того, что бы твоя виртуальная папка с твоими виртуальными файлами отображалась в простом проводнике. А как все заработает, то ее можно будет скрыть, и уже получать IDLIST через IShellFolder2.
Re[11]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 21.11.13 08:10
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Здравствуйте, M3fN, Вы писали:


MN>>Как их теперь использовать для получения виртуальных id? Google "Using namespace shell extension" выдаёт ничего.


A>Я думаю, что стоит начать с того, что бы твоя виртуальная папка с твоими виртуальными файлами отображалась в простом проводнике. А как все заработает, то ее можно будет скрыть, и уже получать IDLIST через IShellFolder2.


Я наверное вас уже достал.
Вот есть например http://msdn.microsoft.com/en-us/magazine/cc188741.aspx#S17 не могу найти там где же всё-таки его хоть как-то использовать, хоть где-то, проект — две библиотеки.
Re[12]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 21.11.13 09:13
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>не могу найти там где же всё-таки его хоть как-то использовать, хоть где-то, проект — две библиотеки.


Поскольку вопрос задается второй раз, то соответственно на первый я отвел не то, что ты хотел услышать. Произошло это, вероятно, по той причине, что я не правильно понял вопрос. Соответственно, перефразируй или задай менее общий вопрос.
Re[13]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 21.11.13 09:29
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Здравствуйте, M3fN, Вы писали:


MN>>не могу найти там где же всё-таки его хоть как-то использовать, хоть где-то, проект — две библиотеки.


A>Поскольку вопрос задается второй раз, то соответственно на первый я отвел не то, что ты хотел услышать. Произошло это, вероятно, по той причине, что я не правильно понял вопрос. Соответственно, перефразируй или задай менее общий вопрос.


Я не представляю как вообще можно использовать собственный shell namespace extension, ведь это просто набор com-классов, как к ним обращаться, будь то встраивание в IExplorerBrowser или использование в простом проводнике.

Вы написали чтобы я попробовал создать виртуальную папку и использовать в простом проводнике, как я понял её можно создать реализуя shell namespace(extension) или, как я нагуглил, что-то там настраивать в IIS (возможно это разные понятия под одним названием?).
Re[14]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: Aniskin  
Дата: 21.11.13 11:40
Оценка:
Здравствуйте, M3fN, Вы писали:

MN>Я не представляю как вообще можно использовать собственный shell namespace extension, ведь это просто набор com-классов, как к ним обращаться, будь то встраивание в IExplorerBrowser или использование в простом проводнике.


Ок. Имеется некое shell namespace extension. В общем случае корневая папка твоего расширения будет иметь виртуальный путь типа такого (GUID-ы взяты наугад) "::{ED228FDF-9EA8-4870-83B1-96B02CFE0D52}\{6C815596-821F-40B3-8A84-643B73A8EB16}" Для того, что бы обратиться к твоим объектам, нужно будет получить интерфейс IShellFolder твоей папки. Это делается примерно следующими вызовами (пишу по памяти):

SHGetDesktopFolder(DesktopFolder)
DesktopFolder.ParseDisplayName(0, nil, '::{ED228FDF-9EA8-4870-83B1-96B02CFE0D52}\{6C815596-821F-40B3-8A84-643B73A8EB16}', Eaten, ItemIDList, Attributes))
DesktopFolder.BindToObject(ItemIDList, nil, IID_IShellFolder, ShellFolder)

Что бы перечислить объекты, нужно вызвать IShellFolder::EnumObjects, что бы получить имя каждого из объектов, нужно вызвать IShellFolder.GetDisplayNameOf и т.д.

Соответственно, полученный ItemIDList можно передать в IExplorerBrowser через IDataObject. И IExplorerBrowser будет отображать твою папку, используя эти же самые вызовы из IShellFolder. Но, наверное, будет проще использовать IExplorerBrowser.BrowseToIDList или IExplorerBrowser.BrowseToObject вместо гемора с IDataObject.

MN>Вы написали чтобы я попробовал создать виртуальную папку и использовать в простом проводнике, как я понял её можно создать реализуя shell namespace(extension)


Ты правильно понял.

MN>или, как я нагуглил, что-то там настраивать в IIS (возможно это разные понятия под одним названием?).


Не знаком с этий аббревиатурой.
Re[15]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
От: M3fN  
Дата: 21.11.13 12:00
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Здравствуйте, M3fN, Вы писали:


MN>>Я не представляю как вообще можно использовать собственный shell namespace extension, ведь это просто набор com-классов, как к ним обращаться, будь то встраивание в IExplorerBrowser или использование в простом проводнике.


A>Ок. Имеется некое shell namespace extension. В общем случае корневая папка твоего расширения будет иметь виртуальный путь типа такого (GUID-ы взяты наугад) "::{ED228FDF-9EA8-4870-83B1-96B02CFE0D52}\{6C815596-821F-40B3-8A84-643B73A8EB16}" Для того, что бы обратиться к твоим объектам, нужно будет получить интерфейс IShellFolder твоей папки. Это делается примерно следующими вызовами (пишу по памяти):


A>SHGetDesktopFolder(DesktopFolder)

A>DesktopFolder.ParseDisplayName(0, nil, '::{ED228FDF-9EA8-4870-83B1-96B02CFE0D52}\{6C815596-821F-40B3-8A84-643B73A8EB16}', Eaten, ItemIDList, Attributes))
A>DesktopFolder.BindToObject(ItemIDList, nil, IID_IShellFolder, ShellFolder)

A>Что бы перечислить объекты, нужно вызвать IShellFolder::EnumObjects, что бы получить имя каждого из объектов, нужно вызвать IShellFolder.GetDisplayNameOf и т.д.


A>Соответственно, полученный ItemIDList можно передать в IExplorerBrowser через IDataObject. И IExplorerBrowser будет отображать твою папку, используя эти же самые вызовы из IShellFolder. Но, наверное, будет проще использовать IExplorerBrowser.BrowseToIDList или IExplorerBrowser.BrowseToObject вместо гемора с IDataObject.


MN>>Вы написали чтобы я попробовал создать виртуальную папку и использовать в простом проводнике, как я понял её можно создать реализуя shell namespace(extension)


A>Ты правильно понял.


MN>>или, как я нагуглил, что-то там настраивать в IIS (возможно это разные понятия под одним названием?).


A>Не знаком с этий аббревиатурой.


Спасибо большое. Буду копать, хотя твой пост пока выглядит так, что всё вроде-бы выкопано.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.