Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
5.1 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. #include "baseloc.h"
  8. static long g_cObj = 0;
  9. static long g_cLock = 0;
  10. static HMODULE ghModule;
  11. static BOOL g_bInit = FALSE;
  12. struct CClassInfo
  13. {
  14. const CLSID* m_pClsid;
  15. IClassFactory* m_pFactory;
  16. LPSTR m_szName;
  17. BOOL m_bFreeThreaded;
  18. };
  19. static CClassInfo g_ClassInfo;
  20. void ObjectCreated()
  21. {
  22. InterlockedIncrement(&g_cObj);
  23. }
  24. void ObjectDestroyed()
  25. {
  26. InterlockedDecrement(&g_cObj);
  27. }
  28. void LockServer(BOOL fLock)
  29. {
  30. if(fLock)
  31. InterlockedIncrement(&g_cLock);
  32. else
  33. InterlockedDecrement(&g_cLock);
  34. }
  35. void SetClassInfo(REFCLSID rclsid, IClassFactory* pFactory, LPSTR szName,
  36. BOOL bFreeThreaded)
  37. {
  38. pFactory->AddRef();
  39. if(g_ClassInfo.m_pFactory)
  40. g_ClassInfo.m_pFactory->Release();
  41. g_ClassInfo.m_pFactory = pFactory;
  42. g_ClassInfo.m_pClsid = &rclsid;
  43. g_ClassInfo.m_szName = new char[strlen(szName) + 1];
  44. strcpy(g_ClassInfo.m_szName, szName);
  45. g_ClassInfo.m_bFreeThreaded = bFreeThreaded;
  46. }
  47. void SetModuleHandle(HMODULE hModule)
  48. {
  49. ghModule = hModule;
  50. }
  51. //***************************************************************************
  52. //
  53. // DllGetClassObject
  54. //
  55. // Purpose: Called by Ole when some client wants a a class factory. Return
  56. // one only if it is the sort of class this DLL supports.
  57. //
  58. //***************************************************************************
  59. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  60. {
  61. if(!g_bInit) // protect // TBD!!!!!
  62. {
  63. DllInitialize();
  64. g_bInit = TRUE;
  65. }
  66. HRESULT hr;
  67. if (*g_ClassInfo.m_pClsid!=rclsid)
  68. return E_FAIL;
  69. IClassFactory* pObj = g_ClassInfo.m_pFactory;
  70. if (NULL==pObj)
  71. return ResultFromScode(E_OUTOFMEMORY);
  72. hr=pObj->QueryInterface(riid, ppv);
  73. return hr;
  74. }
  75. //***************************************************************************
  76. //
  77. // DllCanUnloadNow
  78. //
  79. // Purpose: Called periodically by Ole in order to determine if the
  80. // DLL can be freed.//
  81. // Return: TRUE if there are no objects in use and the class factory
  82. // isn't locked.
  83. //***************************************************************************
  84. STDAPI DllCanUnloadNow(void)
  85. {
  86. SCODE sc;
  87. //It is OK to unload if there are no objects or locks on the
  88. // class factory.
  89. sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  90. return sc;
  91. }
  92. //***************************************************************************
  93. //
  94. // DllRegisterServer
  95. //
  96. // Purpose: Called during initialization or by regsvr32.
  97. //
  98. // Return: NOERROR if registration successful, error otherwise.
  99. //***************************************************************************
  100. STDAPI DllRegisterServer(void)
  101. {
  102. if(!g_bInit) // protect // TBD!!!!!
  103. {
  104. DllInitialize();
  105. g_bInit = TRUE;
  106. }
  107. char szID[128];
  108. WCHAR wcID[128];
  109. char szCLSID[128];
  110. char szModule[MAX_PATH];
  111. HKEY hKey1, hKey2;
  112. // Create the path.
  113. StringFromGUID2(*g_ClassInfo.m_pClsid, wcID, 128);
  114. wcstombs(szID, wcID, 128);
  115. lstrcpy(szCLSID, TEXT("CLSID\\"));
  116. lstrcat(szCLSID, szID);
  117. // Create entries under CLSID
  118. RegCreateKey(HKEY_CLASSES_ROOT, szCLSID, &hKey1);
  119. RegSetValueEx(hKey1, NULL, 0, REG_SZ,
  120. (BYTE *)g_ClassInfo.m_szName,
  121. lstrlen(g_ClassInfo.m_szName)+1);
  122. RegCreateKey(hKey1,"InprocServer32",&hKey2);
  123. GetModuleFileName(ghModule, szModule, MAX_PATH);
  124. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule,
  125. lstrlen(szModule)+1);
  126. const char* szModel;
  127. if(g_ClassInfo.m_bFreeThreaded)
  128. {
  129. szModel = "Both";
  130. }
  131. else
  132. {
  133. szModel = "Apartment";
  134. }
  135. RegSetValueEx(hKey2, "ThreadingModel", 0, REG_SZ,
  136. (BYTE *)szModel, lstrlen(szModel)+1);
  137. CloseHandle(hKey1);
  138. CloseHandle(hKey2);
  139. return NOERROR;
  140. }
  141. //***************************************************************************
  142. //
  143. // DllUnregisterServer
  144. //
  145. // Purpose: Called when it is time to remove the registry entries.
  146. //
  147. // Return: NOERROR if registration successful, error otherwise.
  148. //***************************************************************************
  149. STDAPI DllUnregisterServer(void)
  150. {
  151. if(!g_bInit) // protect // TBD!!!!!
  152. {
  153. DllInitialize();
  154. g_bInit = TRUE;
  155. }
  156. char szID[128];
  157. WCHAR wcID[128];
  158. char szCLSID[128];
  159. HKEY hKey;
  160. // Create the path using the CLSID
  161. StringFromGUID2(*g_ClassInfo.m_pClsid, wcID, 128);
  162. wcstombs(szID, wcID, 128);
  163. lstrcpy(szCLSID, TEXT("CLSID\\"));
  164. lstrcat(szCLSID, szID);
  165. // First delete the InProcServer subkey.
  166. DWORD dwRet = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hKey);
  167. if(dwRet == NO_ERROR)
  168. {
  169. RegDeleteKey(hKey, "InProcServer32");
  170. CloseHandle(hKey);
  171. }
  172. dwRet = RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", &hKey);
  173. if(dwRet == NO_ERROR)
  174. {
  175. RegDeleteKey(hKey,szID);
  176. CloseHandle(hKey);
  177. }
  178. return NOERROR;
  179. }