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.

240 lines
6.5 KiB

  1. //***************************************************************************
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Module: WMI Framework Instance provider
  6. //
  7. // Purpose: Contains DLL entry points. Also has code that controls
  8. // when the DLL can be unloaded by tracking the number of
  9. // objects and locks as well as routines that support
  10. // self registration.
  11. //
  12. // Copyright (c)1999 Microsoft Corporation, All Rights Reserved
  13. //
  14. //***************************************************************************
  15. #include "pchealth.h"
  16. HMODULE g_hModule;
  17. //============
  18. WCHAR *GUIDSTRING = L"{5d24c539-5b5b-11d3-8ddd-00c04f688c0b}";
  19. CLSID CLSID_PRINTSYS;
  20. // Count number of objects and number of locks.
  21. long g_cLock = 0;
  22. // Keep a global IWbemServices pointer, since we use it frequently and
  23. // it's a little expensive to get.
  24. CComPtr<IWbemServices> g_pWbemServices = NULL;
  25. //***************************************************************************
  26. //
  27. // DllGetClassObject
  28. //
  29. // Purpose: Called by Ole when some client wants a class factory. Return
  30. // one only if it is the sort of class this DLL supports.
  31. //
  32. //***************************************************************************
  33. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  34. {
  35. CWbemGlueFactory *pObj;
  36. HRESULT hr;
  37. CLSIDFromString(GUIDSTRING, &CLSID_PRINTSYS);
  38. if (rclsid != CLSID_PRINTSYS)
  39. return E_FAIL;
  40. pObj = new CWbemGlueFactory();
  41. if (NULL == pObj)
  42. return E_OUTOFMEMORY;
  43. hr = pObj->QueryInterface(riid, ppv);
  44. if (FAILED(hr))
  45. delete pObj;
  46. return hr;
  47. }
  48. //***************************************************************************
  49. //
  50. // DllCanUnloadNow
  51. //
  52. // Purpose: Called periodically by Ole in order to determine if the
  53. // DLL can be freed.
  54. //
  55. // Return: S_OK if there are no objects in use and the class factory
  56. // isn't locked.
  57. //
  58. //***************************************************************************
  59. STDAPI DllCanUnloadNow(void)
  60. {
  61. SCODE sc;
  62. // It is OK to unload if there are no objects or locks on the
  63. // class factory and the framework is done with you.
  64. if ((g_cLock == 0) && CWbemProviderGlue::FrameworkLogoffDLL(L"PRINTSYS"))
  65. sc = S_OK;
  66. else
  67. sc = S_FALSE;
  68. return sc;
  69. }
  70. //***************************************************************************
  71. //
  72. // Is4OrMore
  73. //
  74. // Returns true if win95 or any version of NT > 3.51
  75. //
  76. //***************************************************************************
  77. BOOL Is4OrMore(void)
  78. {
  79. OSVERSIONINFO os;
  80. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  81. if(!GetVersionEx(&os))
  82. return FALSE; // should never happen
  83. return os.dwMajorVersion >= 4;
  84. }
  85. //***************************************************************************
  86. //
  87. // DllRegisterServer
  88. //
  89. // Purpose: Called during setup or by regsvr32.
  90. //
  91. // Return: NOERROR if registration successful, error otherwise.
  92. //***************************************************************************
  93. STDAPI DllRegisterServer(void)
  94. {
  95. WCHAR wcID[128];
  96. HKEY hKey1, hKey2;
  97. char szID[128];
  98. char szCLSID[128];
  99. char szModule[MAX_PATH];
  100. char *pName = "";
  101. char *pModel;
  102. if(Is4OrMore())
  103. pModel = "Both";
  104. else
  105. pModel = "Apartment";
  106. // Create the path.
  107. CLSIDFromString(GUIDSTRING, &CLSID_PRINTSYS);
  108. StringFromGUID2(CLSID_PRINTSYS, wcID, 128);
  109. wcstombs(szID, wcID, 128);
  110. lstrcpy(szCLSID, TEXT("SOFTWARE\\CLASSES\\CLSID\\"));
  111. lstrcat(szCLSID, szID);
  112. // Create entries under CLSID
  113. RegCreateKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey1);
  114. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)pName, lstrlen(pName)+1);
  115. RegCreateKey(hKey1,"InprocServer32",&hKey2);
  116. GetModuleFileName(g_hModule, szModule, MAX_PATH);
  117. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule,
  118. lstrlen(szModule)+1);
  119. RegSetValueEx(hKey2, "ThreadingModel", 0, REG_SZ,
  120. (BYTE *)pModel, lstrlen(pModel)+1);
  121. CloseHandle(hKey1);
  122. CloseHandle(hKey2);
  123. return NOERROR;
  124. }
  125. //***************************************************************************
  126. //
  127. // DllUnregisterServer
  128. //
  129. // Purpose: Called when it is time to remove the registry entries.
  130. //
  131. // Return: NOERROR if registration successful, error otherwise.
  132. //***************************************************************************
  133. STDAPI DllUnregisterServer(void)
  134. {
  135. WCHAR wcID[128];
  136. HKEY hKey;
  137. char szID[128];
  138. char szCLSID[128];
  139. // Create the path using the CLSID
  140. CLSIDFromString(GUIDSTRING, &CLSID_PRINTSYS);
  141. StringFromGUID2(CLSID_PRINTSYS, wcID, 128);
  142. wcstombs(szID, wcID, 128);
  143. lstrcpy(szCLSID, TEXT("SOFTWARE\\CLASSES\\CLSID\\"));
  144. lstrcat(szCLSID, szID);
  145. // First delete the InProcServer subkey.
  146. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey);
  147. if(dwRet == NO_ERROR)
  148. {
  149. RegDeleteKey(hKey, "InProcServer32");
  150. CloseHandle(hKey);
  151. }
  152. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\CLASSES\\CLSID\\"), &hKey);
  153. if(dwRet == NO_ERROR)
  154. {
  155. RegDeleteKey(hKey,szID);
  156. CloseHandle(hKey);
  157. }
  158. return NOERROR;
  159. }
  160. //***************************************************************************
  161. //
  162. // DllMain
  163. //
  164. // Purpose: Called by the operating system when processes and threads are
  165. // initialized and terminated, or upon calls to the LoadLibrary
  166. // and FreeLibrary functions
  167. //
  168. // Return: TRUE if load was successful, else FALSE
  169. //***************************************************************************
  170. BOOL APIENTRY DllMain (HINSTANCE hInstDLL, // handle to dll module
  171. DWORD fdwReason, // reason for calling function
  172. LPVOID lpReserved) // reserved
  173. {
  174. BOOL bRet = TRUE;
  175. // Perform actions based on the reason for calling.
  176. switch( fdwReason )
  177. {
  178. case DLL_PROCESS_ATTACH:
  179. DisableThreadLibraryCalls(hInstDLL);
  180. g_hModule = hInstDLL;
  181. bRet = CWbemProviderGlue::FrameworkLoginDLL(L"PRINTSYS");
  182. break;
  183. case DLL_THREAD_ATTACH:
  184. // Do thread-specific initialization.
  185. break;
  186. case DLL_THREAD_DETACH:
  187. // Do thread-specific cleanup.
  188. break;
  189. case DLL_PROCESS_DETACH:
  190. // Perform any necessary cleanup.
  191. break;
  192. }
  193. return bRet; // Sstatus of DLL_PROCESS_ATTACH.
  194. }