Если клиент осуществляет такой запрос на активацию:
IApeClass *рас = 0;
HRESULT hr = CoGetClassObject(CLSID_Chimp, CLSCTX_REMOTE_SERVER, 0, IID_IApeClass, (void**)&pac);
то SCM со стороны клиента направит этот запрос в SCM на www.apes.com , где этот запрос будет рассмотрен как локальный активационный запрос. Отметим, что если клиент предоставляет явное хост-имя:
IApeClass *рас = 0;
COSERVERINFO csi;
ZeroMemory(&csi, sizeof(csi));
csi.pwszName = OLESTR(www.dogs.com);
HRESULT hr = CoGetClassObject(CLSID_Chimp, CLSCTX_REMOTE_SERVER, &csi, IID_IApeClass, (void**)&pac);
то установка RemoteServerName игнорируется и запрос направляется в www.apes.com.
Чаще встречается ситуация, когда клиенты не указывают явно свои предпочтения относительно хост-имени и месторасположения. Рассмотрим следующий вызов CoGetClassObject
IApeClass *pac = 0;
HRESULT hr = CoGetClassObject(CLSID_Chimp, CLSCTX_ALL, 0, IID_IApeClass, (void*)&pac);
Поскольку не указано никакого хост-имени, то SCM сначала будет искать в локальном реестре следующий ключ:
[HKCR\AppID\{27EE6A4F-DF65-11d0-8C5F-0080C7392SBA}]
Если этот ключ локально не доступен, COM обратится к хранилищу класса (class store) под Windows NT 5.0, если оно доступно. Если с этой точки зрения ключ реестра доступен, то вслед за этим SCM будет искать подключ InpocServer32:
HKCR\CLSID\{27EE6A4F-DF65-11d0-8C5F-0080C73925BA}\InprocServer32] @="C:\somefile.dll"
Если этот ключ найден, класс будет активирован путем загрузки той DLL, которая указана в реестре. В противном случае SCM ищет подключ InprocHandler32 :
HKCR\CLSID\{27EE6A4F-DF65-11d0-8C5F-0080C73925BA}\InprocHandler32] @="C:\somefile.dll"
Если класс имеет ключ дескриптора (handler), то и тогда класс будет активирован путем загрузки той DLL, которая указана в реестре. Если ни один из внутрипроцессных подключей не доступен, то SCM предполагает, что активационный запрос должен быть внепроцессным. В таком случае SCM проверяет, имеет ли серверный процесс объект класса, зарегистрированный в настоящее время для запрашиваемого CLSID[1]. Если это так, то SCM входит в серверный процесс и маршалирует объектную ссылку из соответствующего объекта класса и возвращает ее в апартамент вызывающего объекта, где она демаршалируется до того, как управление возвращается к вызывающему объекту. Если объект класса был зарегистрирован серверным процессом с флагом REGCLS_SINGLEUSE, то SCM затем забывает, что класс доступен в серверном процессе и не будет использовать его для последующих запросов на активацию.
Только что описанный сценарий является корректным, если серверный процесс уже выполняется. Если, однако, SCM получает внепроцессный запрос на активацию, но под запрашиваемым CLSID не зарегистрировался ни один серверный процесс, то SCM запустит серверный процесс, который еще не запущен. COM поддерживает три модели для создания серверов: сервисы NT (NT Services), нормальные процессы и суррогатные процессы (surrogate processes). NT Services и нормальные процессы очень похожи, и причины, по которым один из них можно предпочесть другому, явятся предметом дальнейшего обсуждения в рамках этой главы. Суррогатные процессы используются в основном для возложения функции ведущего узла на старые внутрипроцессные серверы в отдельных серверных процессах. Это дает преимущества удаленной активации и локализации ошибок для старых DLL или для классов, которые должны быть упакованы как DLL (например, виртуальная машина Java). Независимо от того, какая модель используется для создания серверного процесса, у серверного процесса есть 120 секунд (или 30 секунд под Windows NT Service Pack 2 и более ранних версий) для регистрации запрошенного объекта класса с применением CoRegisterClassObject. Если серверный процесс не может вовремя зарегистрировать сам себя, то SCM откажет вызывающему объекту в запросе на активацию.
При создании серверного процесса SCM вначале проверяет, имеет ли AppID, соответствующий запрашиваемому классу, именованную величину LocalService:
[HKCR\AppID\{27EE6A4D-DF65-11d0-8C5F-0080C73925BA} LocalService="apesvc"
Если это именованное значение имеется, то SCM использует NT Service Control Manager (диспетчер управления сервисами) для запуска той службы NT, которая указана в реестре (например, apesvc). Если же именованная величина LocalService отсутствует, то в этом случае SCM ищет в указанном CLSID ключе подключ LocalServer32:
[HKCR\CLSID\{27EE6A4F-DF65-11d0-8C5F-0080C73925BA}\LocalServer32] @="C:\somefile.exe"
Если этот ключ присутствует, то SCM применит для запуска серверного процесса API-функцию CreateProcess (или CreateProcessAsUser). В случае отсутствия и LocalService, и LocalServer32, SCM ищет, определен ли для AppID -класса суррогатный процесс:
[HKCR\AppID\{27EE6A4D-DF6S-11d0-8CSF-0080C73925BA}] DllSurrogate=""