Имя mapped network drive в explorer'е
От: Ulin США  
Дата: 31.08.07 11:09
Оценка:
Обчыно при маппинге сетевой шары отображаемое в explorer имя диска можно задать в следующем ключе реестра (WinXP):
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\##server#share\_LabelFromReg
Cобственно ключ ##server#share создается explorer'ом в момент замапливания.

Однако при маппинге шары через написанный нами network redirector, explorer вместо ключа ##server#share
почему-то создает в MountPoints2 ключик, именованный каким-то гуидом, что-нить типа {A673C6F4-2D7B-43FF-B2D9-DD10052B91D1}
И имя диска читает исключительно оттуда, игнорируя мои попытки подсунуть ему ключ ##server#share.

Может быть кто-то разбирался в логике explorer'а в этом моменте? Почему имя ключа становится гуидом? Есть подозрения, что
наш Network provider dll сообщает что-то explorer'у, что заставляет его так поступать...

На крайний случай, может есть способ узнать, какой гуид сопоставил explorer с нашем замапленным диском, чтобы хотя бы вписать
в этот ключ реестра нужное имя?
Re: Имя mapped network drive в explorer'е
От: Vacabi  
Дата: 02.09.07 23:22
Оценка:
Здравствуйте, Ulin, Вы писали:

U>На крайний случай, может есть способ узнать, какой гуид сопоставил explorer с нашем замапленным диском, чтобы хотя бы вписать

U>в этот ключ реестра нужное имя?

А вы чего хотите добиться? Назначить своему диску какое-то имя? Так может через парадный вход попробовать, IShellFolder::SetNameOf?
Мои ¢2
-- Vacabi
Re[2]: Имя mapped network drive в explorer'е
От: Ulin США  
Дата: 03.09.07 06:50
Оценка:
Здравствуйте, Vacabi, Вы писали:

V>А вы чего хотите добиться? Назначить своему диску какое-то имя? Так может через парадный вход попробовать, IShellFolder::SetNameOf?


Ессно пороги парадного входа отбиты донельзя. Все отлично отрабатывает, в реестре появляется красивый ключик ##server#share с выставленным мною именем. Но explorer упорно продолжает игнорировать этот ключ, и юзать данные из ключа в виде GUID'а, который он создал для диска при монтировании...
Перезапуск процесса explorer.exe в принципе помогает, но это ессно не вариант.
Re[3]: Имя mapped network drive в explorer'е
От: Vacabi  
Дата: 03.09.07 07:56
Оценка:
Здравствуйте, Ulin, Вы писали:

U>Перезапуск процесса explorer.exe в принципе помогает, но это ессно не вариант.


А SHChangeNotify вы вызываете?
Мои ¢2
-- Vacabi
Re[4]: Имя mapped network drive в explorer'е
От: Ulin США  
Дата: 03.09.07 08:48
Оценка:
Здравствуйте, Vacabi, Вы писали:

V>А SHChangeNotify вы вызываете?


Вообще-то нет. Судя по следующей фразе из MSDN вроде и не должен:

Implementers of IShellFolder::SetNameOf must call SHChangeNotify with both the old and new absolute PIDLs once the renaming of an object is complete


Вроде как в данной ситуации я скорее caller, чем implementer..

В качестве шаманства попробовал вызвать. Код получился такой:

    LPITEMIDLIST                pItemList        = 0;
    STRRET                                Name;
    IShellFolder                        *pFolder        = 0;
    IShellFolder                        *pSubFolder    = 0;
    IEnumIDList                        *pEnum            = 0;

    wchar_t pBuf[MAX_PATH] = {0};
    wchar_t wszTmp[2048] = {0};

    ((wchar_t*)pBuf)[0] = drive[0];
    ((wchar_t*)pBuf)[1] = L':';
    ((wchar_t*)pBuf)[2] = L'\\';
    ((wchar_t*)pBuf)[3] = 0;

    HRESULT hr = ::SHGetDesktopFolder(&pFolder);
    if (FAILED(hr))
        return;

    hr = ::SHGetSpecialFolderLocation(0, CSIDL_DRIVES, &pItemList);
    if (FAILED(hr))
        return;

    hr = pFolder->BindToObject(pItemList, 0, IID_IShellFolder, (void**)&pSubFolder);
    if (FAILED(hr))
        return;

    ::CoTaskMemFree(pItemList);
    hr = pSubFolder->EnumObjects(0, SHCONTF_STORAGE, &pEnum);
    if (FAILED(hr))
        return;

    while (pEnum->Next(1, &pItemList, 0) != S_FALSE)
    {
        hr = pSubFolder->GetDisplayNameOf(pItemList, SHGDN_FORPARSING, &Name);
        if (FAILED(hr))
            return;

        hr = ::StrRetToBufW(&Name, pItemList, wszTmp, 2048);
        if (FAILED(hr))
            return;

        if (!lstrcmpiW(wszTmp, pBuf))
        {
            LPITEMIDLIST  newItemList = NULL;
            hr = pSubFolder->SetNameOf(0, pItemList, SHARE_LABEL
                , SHGDN_INFOLDER | SHGDN_FOREDITING, &newItemList);

            if (FAILED(hr))
                return;

            ::SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_IDLIST, pItemList, newItemList);

            break;
        }
        ::CoTaskMemFree(pItemList);
        pItemList = 0;
    }


Результат тот же
Re[5]: Имя mapped network drive в explorer'е
От: Vacabi  
Дата: 03.09.07 09:31
Оценка:
Здравствуйте, Ulin, Вы писали:

V>>А SHChangeNotify вы вызываете?


U>Вообще-то нет. Судя по следующей фразе из MSDN вроде и не должен:


U>

U>Implementers of IShellFolder::SetNameOf must call SHChangeNotify with both the old and new absolute PIDLs once the renaming of an object is complete


Вроде получается не должен, но попробовать стоит.

U>Результат тот же


В SHChangeNotify надо абсолютные PIDL давать, а у вас вроде относительно My Computer получается.
Мои ¢2
-- Vacabi
Re[6]: Имя mapped network drive в explorer'е
От: Ulin США  
Дата: 03.09.07 13:19
Оценка:
Здравствуйте, Vacabi, Вы писали:

V>В SHChangeNotify надо абсолютные PIDL давать, а у вас вроде относительно My Computer получается.


Что-то не очень понял как из относительного PIDL сделать абсолютный... Судя по линкам, которые дает гугл, есть какой-то pidl manager, но доступен он я так понимаю только IShelFolder implementators...
Re[7]: Имя mapped network drive в explorer'е
От: Ulin США  
Дата: 03.09.07 14:37
Оценка: 1 (1)
Источник проблемы выяснен и устранен.
В процессе выполнения NPAddConnection вызывается функция NPGetConnection этого же Network Provider'а.
Если этот вызов NPGetConnection сфейлится, explorer, не получив нормального имени соединения, создает в MountPoints2 ветку-GUID. И далее работает только с ней. Любые попытки изменить display name далее просто игнорятся.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.