Размонтирование, а затем сразу же перемонтирование общего ресурса SMB при сбое другого пользователя - PullRequest
2 голосов
/ 17 февраля 2012

Я работаю над приложением MFC, которое работает под управлением Windows XP SP3. Одним из требований является то, что когда пользователь входит в приложение, приложение должно подключить несколько общих ресурсов SMB, размещенных на встроенном сервере Linux, используя учетные данные этого пользователя.

Программа имеет функцию «переключить пользователя», которая позволяет другому пользователю войти в систему, не закрывая приложение, и завершить сеанс первого пользователя. Когда это происходит, общие ресурсы SMB должны быть отключены, а затем повторно подключены как новый пользователь.

Мы делаем это, вызывая WNetCancelConnection2, а затем сразу WNetAddConnection2. WNetCancelConnection2 возвращает NO_ERROR, указывая, что это было успешно. Однако иногда WNetAddConnection2 не удается перемонтировать диск как нового пользователя. Использование FormatMessage для получения строки ошибки из возвращаемого значения приводит к этому сообщению об ошибке, несмотря на то, что WNetCancelConnection2 казалось добиться успеха:

Несколько подключений к серверу или общему ресурсу одним и тем же пользователем с использованием нескольких имен пользователей не допускаются. Отключите все предыдущие подключения к серверу или общему ресурсу и повторите попытку.

Запуск net use из командной строки также не показывает открытого соединения с общим ресурсом SMB.

Этот сбой не произойдет, если пользователь никогда не взаимодействует с подключенным диском. Это происходит только в том случае, если пользователь каким-то образом получил доступ к подключенному диску, то есть пользователь открыл подключенный диск в проводнике Windows. Аналогично, это не произойдет, если вы полностью закроете приложение, а затем перезапустите его и войдете в систему как другой пользователь.

Все это заставляет меня поверить, что существует условие гонки, при котором WNetCancelConnection2 возвращается до того, как все открытые хэндлы к сетевому ресурсу закрыты. У меня вопрос , могу ли я сделать свой программный блок или подождать после вызова WNetCancelConnection2, пока все эти дескрипторы не будут закрыты, гарантируя, что WNetAddConnection2 не выйдет из строя таким образом? Либо блокирующий API, либо способ Ожидание занятости до полного закрытия соединения будет приемлемым. Любой из них будет предпочтительнее sleep() и надеюсь на лучшее. : -)

...