Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Single Post  Topic: Подмена "штатного" сетевого окружения при возврате с хоста 
Author Message
MVV



PostPosted: Mon Apr 19, 2010 18:04    Post subject: Reply with quote

HankHank wrote:
Попробовал приладить код с вызовом фонового процесса, получилось так:
Code:

...

Компиллятор не взбрыкнул. Нужный процесс рождается. Код возврата thread ненулевой. Но эффекта - нет. Так и стоим на месте - на [..]. Подробнее пока не глядел.
Может, свежим взглядом косяк виден сразу ?

Ну молодец! Так и до вылета ТК в трубу недалеко. Very Happy

А теперь поясняю, что у тебя происходит. Ты выделил в стеке место для буфера и вписал в него путь. Далее, ты вызываешь фоновую функцию и передаешь ей адрес этого буфера, и не дожидаясь ее завершения выходишь из функции, в которой буфер был выделен, то есть, уничтожаешь его! Что будет? Система при отправке сообщения WM_COPYDATA скопирует указанное число байт по указанному адресу в свой буфер (заметь, там уже может быть что угодно, так как основной поток продолжает работать и использовать стек по своему усмотрению) и отправит сообщение ТК, указав новый адрес буфера (функция позволяет передавать буфера между процессами, поэтому она переписывает данные в буфер в адресном пространстве процесса-получателя). Итак, ТК просто получит мусор. Но хрен его знает, насколько правильно он этот мусор интерпретирует.

Выход? Выделять память динамически. Ты убрал юникод из функции - да, это тебе не нужно. Но советую вернуть назад динамическое выделение памяти, без него передавать что-либо в другой поток не советую. В моих функциях память выделялась динамически и передавался указатель на выделенный буфер, который затем освобождался функцией в фоновом потоке.

Еще один момент - плагин у юзера необязательно будет называться "net", имя можно дать любое в настройке FS-плагинов.


Кстати, заметил, что у меня может теряться память, если будет ошибка создания фонового потока. Модернизировал:
Code:
struct BackgroundSendDataData {
   COPYDATASTRUCT CopyData;
   char Raw[0];
};

DWORD __stdcall BackgroundSendData(void* Data) {
   BackgroundSendDataData* bsd=(BackgroundSendDataData*)Data;
   auto_ptr<char> ash((char*)Data);
   SendMessage(hMainWnd, WM_COPYDATA, 0, (LPARAM)&bsd->CopyData);
   return 0;
}

bool ChangeCurrentDir(const wchar_t* Path, bool NewTab) {
   int length=lstrlen(Path);
   auto_ptr<char> ash(new char[sizeof(BackgroundSendDataData)+20+2*length]);
   BackgroundSendDataData* bsd=(BackgroundSendDataData*)ash.get();

   bsd->CopyData.dwData='DC';
   bsd->CopyData.lpData=bsd->Raw;
   char* p=bsd->Raw;
   if (Unicode) p+=wsprintfA(p, "\xEF\xBB\xBF");
   p+=WideCharToMultiByte(Unicode ? CP_UTF8 : CP_ACP, 0, Path, length, p, 2*length, 0, 0);
   p+=wsprintfA(p, "\r%cS%s", 0, NewTab ? "T" : "");
   bsd->CopyData.cbData=p-bsd->Raw+1;

   HANDLE thread=CreateThread(0, 0, &BackgroundSendData, ash.get(), 0, 0);
   if (!thread) return 0;

   ash.release();
   CloseHandle(thread);
   return 1;
}

(заодно сделал структуру буфера более понятной - вначале идет COPYDATASTRUCT, а сразу за ней - буфер произвольной длины, адрес и размер которого она содержит)

И ANSI-версия ChangeCurrentDir (вроде так, проверить нет времени; функция фонового потока общая):
Code:
bool ChangeCurrentDir(const char* Path, bool NewTab) {
   int length=lstrlen(Path);
   auto_ptr<char> ash(new char[sizeof(BackgroundSendDataData)+20+length]);
   BackgroundSendDataData* bsd=(BackgroundSendDataData*)ash.get();

   bsd->CopyData.dwData='DC';
   bsd->CopyData.lpData=bsd->Raw;
   char* p=bsd->Raw;
   p+=wsprintf(p, "%s\r%cS%s", Path, length, 0, NewTab ? "T" : "");
   bsd->CopyData.cbData=p-bsd->Raw+1;

   HANDLE thread=CreateThread(0, 0, &BackgroundSendData, ash.get(), 0, 0);
   if (!thread) return 0;

   ash.release();
   CloseHandle(thread);
   return 1;
}



На оффтоп отвечать не буду, раз модераторы против. Хотя, могу в личку.


HankHank wrote:
При нахождении “в среде плагина” попытка ввести “cd \\< IP или имя>” не приводит к успеху – надо слегка подриххтовать логику. Ты, впрочем, об этом вскользь уже говорил.

Заметил этот абзац - и возник вопрос. Ты вводишь команду для перехода в сетевую папку, находясь в папке плагина, и оно не работает (в ТК команда cd не работает в папках FS-плагинов; ты должен вручную реализовать обработку команды cd и изменить текущую папку - например, вызвав ChangeCurrentDir, как делает моя VirtualPanel), или ты пытаешься обойти хук с помощью команды cd (я говорил как раз об этом - не нужно блокировать команду cd, раз юзер пишет ее, у него есть на то причины), или же этот абзац тоже подразумевает установку текста командной строки и выполнение для смены папки (маловероятно, что ты имел в виду это, но вдруг)?
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…
View user's profile Send private message ICQ Number


Powered by phpBB © 2001, 2005 phpBB Group