ASP .NET + WebMethod + func. DllRegisterServer fails with error 0x80004005
Я тут пишу WebService (MS VS 2005 && IIS 7.0 on MS Vista), метод которого регистрирует на сервере COM-компонент (на настоящий момент вызов метода и деятельность метода происходят на одной машине). Для этого я сначала гружу необходимую DLL, достаю функцию DllRegisterServer и вызываю её. При этом, получаю ошибку 0x80004005. При этом, если регистрировать через командную строку или вообще - создать обычное приложение ввиде формы и кнопки (в которую засунуть функционал метода), то всё будет работать.
Т.е. дело явно в ASP .NET или в IIS. Что делать? Бьюсь об стенку уже четвёртый день.
На всякий случай кину исходник:
#define COM_SERV_FILE "COMNet.dll"
String ^ASPClass::InstallCOMServer(void)
// "fpath" = FilePATH
{
String ^res = "[Info] COM-Server was successfully registered";
// getting path to COM-Server DLL
String ^src_fpath = Server->MapPath(SRC_FILE);
String ^curr_dir = src_fpath->Substring(0, src_fpath->LastIndexOf("\\") + 1);
String ^cs_fpath = curr_dir + COM_SERV_FILE; // "cs" = ComServer
// loading COM-Server DLL
char* str1 = (char*)(void*)Marshal::StringToHGlobalAnsi(cs_fpath);
HMODULE hmod = LoadLibraryA( str1 );
Marshal::FreeHGlobal(IntPtr(str1));
if (hmod == NULL) return "[Error] LoadLibraryA fails ("
+ cs_fpath + ")!";
// getting and calling function from DLL
HRESULT (WINAPI * DLL_REG_SERV)(void);
(FARPROC&) DLL_REG_SERV = GetProcAddress(hmod, "DllRegisterServer");
if (DLL_REG_SERV == NULL)
{
FreeLibrary(hmod);
return "[Error] Cannot find DllRegisterServer function in COM-Server DLL ("
+ cs_fpath + ")!";
}
DWORD nres = DLL_REG_SERV(); // "nres" = NumberRESult
if (nres >= 2147500032)
res = "[Error] COM-Server wasn't successfully registered (res == 0x" + nres.ToString("x") + ")";
// freeing DLL
FreeLibrary(hmod);
return res;
}
После этого имеем: "[Error] COM-Server wasn't successfully registered (res == 0x80004005)"
Да, мой пользователь входит в группу "Администраторы".
Райт-кликнуть по чему? По *.asmx файлу? Там не будет такого пункта. Этот файл нужно запускать через web-browser.
Т.е. использовать что-то типа Regmon или FileMon? Эм... Вот только не понятно как должна выглядеть нужная мне информация.
Что я только не делал. Пробовал и другую библиотеку пихать. - не регит.
Но, если использовать или regsvr32 или просто, написать EXE-приложение, то всё будет ОК.
Эм... Ну, смысл, впринципе этот. Просто, я текст этой ошибки формирую сам (см. код вэб-метода в первом посте).
И наконец, помучьте поисковики, там по Вашей теме несколько вариантов было.
Жесть. При дэбаггинге сначало всё зависло. Я экстренно вырубил комп.
Включил. Служба IIS не стартует. Попытался переустановить, но результат один и тот же - при попытке стартонуть IIS пишется: "Не удалось запустить службу W3SVC на компьютере '.'."
Всё. Приехали.
Служба "Служба веб-публикаций" не запущена.
Для вызова дополнительной справки наберите NET HELPMSG 3521.
C:\>net start w3svc
Системная ошибка 1068.
Не удалось запустить дочернюю службу.
Жесть!
Ошибка 13: Недопустимые данные."
Да надо бы уже. =) Просто хочу проектик один закончить.
Лучше не надо. Я тут много чего настроил. Очень не хотелось бы переустанавливать...
Ну вот я же вам и говорил, что с правами порблема и чтобы все було под админом :)
Кстати, а в линуксе "Службы активации" нет.... :rolleyes:
Короче говоря не в этом проблема была. Я ошибался, наивн полагая, что проблема именно в привилегиях пользователя ASPNET. Я его включил и в группу "Администраторы" и в группу "Debugger Users" -- не работает. Ещё там пользователь есть IUSR_<%NAME_OF_USER%> я и с ним проделал тоже самое -- и всё равно нихрена не работает.
Всё. Кабздец. Уже полторы недели торчу на одном месте. Люди! Помогите!
ЫЫЫ... Вы хотите сказать, что переустановка что-то сможет решить? Я в этом глубоко сомневаюсь. Да и вообще - лучше разобраться в чём же был баг, и, если это баг мягкомелких, то сообщить им об этом - пусть исправят и совершенствуют свою ОС. =)
Да Вам виднее, если не лень и не срочно - то рабирайтесь. :)
А на счет чего-то совершенного от мелких, так это... интересный вопрос, правда уже не этой темы. ))
Вот привилегии процесса, под которым COM-сервер не регистрируется:
Замена маркера уровня процесса - SeAssignPrimaryTokenPrivilege
Настройка квот памяти для процесса - SeIncreaseQuotaPrivilege
Завершение работы системы - SeShutdownPrivilege
Создание аудитов безопасности - SeAuditPrivilege
Обход перекрестной проверки - SeChangeNotifyPrivilege
Отключение компьютера от стыковочного узла - SeUndockPrivilege
Имитация клиента после проверки подлинности - SeImpersonatePrivilege
Создание глобальных объектов - SeCreateGlobalPrivilege
Увеличение рабочего набора процесса - SeIncreaseWorkingSetPrivilege
Изменение часового пояса - SeTimeZonePrivilege
А вот привилегии процесса, под которым всё ОК:
Настройка квот памяти для процесса - SeIncreaseQuotaPrivilege
Управление аудитом и журналом безопасности - SeSecurityPrivilege
Смена владельцев файлов и других объектов - SeTakeOwnershipPrivilege
Загрузка и выгрузка драйверов устройств - SeLoadDriverPrivilege
Профилирование производительности системы - SeSystemProfilePrivilege
Изменение системного времени - SeSystemtimePrivilege
Профилирование одного процесса - SeProfileSingleProcessPrivilege
Увеличение приоритета выполнения - SeIncreaseBasePriorityPrivilege
Создание файла подкачки - SeCreatePagefilePrivilege
Архивация файлов и каталогов - SeBackupPrivilege
Восстановление файлов и каталогов - SeRestorePrivilege
Завершение работы системы - SeShutdownPrivilege
Отладка программ - SeDebugPrivilege
Изменение параметров среды изготовителя - SeSystemEnvironmentPrivilege
Обход перекрестной проверки - SeChangeNotifyPrivilege
Принудительное удаленное завершение работы - SeRemoteShutdownPrivilege
Отключение компьютера от стыковочного узла - SeUndockPrivilege
Выполнение задач по обслуживанию томов - SeManageVolumePrivilege
Имитация клиента после проверки подлинности - SeImpersonatePrivilege
Создание глобальных объектов - SeCreateGlobalPrivilege
Увеличение рабочего набора процесса - SeIncreaseWorkingSetPrivilege
Изменение часового пояса - SeTimeZonePrivilege
Создание символических ссылок - SeCreateSymbolicLinkPrivilege
Очевидно, что нужно каким-то образом добавить какие-нибудь привилегии процессу (например, SeDebugPrivilege). Но как это сделать?
The SetTokenInformation function sets various types of information for a specified access token. The information that this function sets replaces existing information. The calling process must have appropriate access rights to set the information.
И как определить - имеет ли процесс изменить свои привилегии?
{
DWORD hToken;
LUID SeDebugNameValue;
TOKEN_PRIVILEGES tkp;
DWORD ReturnLength;
BOOL Result;
Result = FALSE;
//Добавляем привилегию SeDebugPrivilege
//Получаем токен нашего процесса
OpenProcessToken(INVALID_HANDLE_VALUE, TOKEN_ADJUST_PRIVILEGES
|| TOKEN_QUERY, (PHANDLE)hToken);
//Получаем LUID привилегии
if (! LookupPrivilegeValueA(NULL, "SeDebugPrivilege", &SeDebugNameValue) ){
CloseHandle((HANDLE)hToken);
return FALSE; }
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = SeDebugNameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//Добавляем привилегию к процессу
AdjustTokenPrivileges((HANDLE)hToken, false, (PTOKEN_PRIVILEGES)&tkp, sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)&tkp, (PDWORD)&ReturnLength);
if ( GetLastError() != ERROR_SUCCESS )
return FALSE;
return TRUE;
}
Но только вот ... оно не работает.
GetLastError() != ERROR_SUCCESS, видимо, из-за того, что нет привилегий на изменение привилегий. =)))
Или я где-то ошибочку допустил?
|| TOKEN_QUERY, (PHANDLE)&hToken);
А теперь GetLastError() возвращает 5, т.е. ERROR_ACCESS_DENIED. =)
Фуф... не ожидал, что установить COM-сервер будет так сложно. =))) LOL