Leaked source code of windows server 2003
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.

338 lines
8.8 KiB

  1. //***************************************************************************
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Module: WBEM Instance provider sample code
  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) 1997-2001 Microsoft Corporation, All Rights Reserved
  13. //
  14. //***************************************************************************
  15. #include "precomp.h"
  16. #include <tchar.h>
  17. #include <objbase.h>
  18. #include <initguid.h>
  19. #include <msiprov.h>
  20. #include "classfac.h"
  21. #include "genericclass.h"
  22. #include "requestobject.h"
  23. // Function pointer type used with LoadMofFiles entrypoint in wbemupgd.dll
  24. typedef BOOL ( WINAPI *PFN_LOAD_MOF_FILES )(wchar_t* pComponentName, const char* rgpszMofFilename[]);
  25. HMODULE ghModule;
  26. DEFINE_GUID(CLSID_MSIprov,0xbe0a9830, 0x2b8b, 0x11d1, 0xa9, 0x49, 0x0, 0x60, 0x18, 0x1e, 0xbb, 0xad);
  27. // {BE0A9830-2B8B-11D1-A949-0060181EBBAD}
  28. //Count number of objects and number of locks.
  29. long g_cObj=0;
  30. long g_cLock=0;
  31. //***************************************************************************
  32. //
  33. // LibMain32
  34. //
  35. // Purpose: Entry point for DLL.
  36. //
  37. // Return: TRUE if OK.
  38. //
  39. //***************************************************************************
  40. BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason
  41. , LPVOID pvReserved)
  42. {
  43. BOOL retVal = TRUE;
  44. if(DLL_PROCESS_DETACH == ulReason){
  45. DeleteCriticalSection(&g_msi_prov_cs);
  46. DeleteCriticalSection(&(CRequestObject::m_cs));
  47. DeleteCriticalSection(&(CGenericClass::m_cs));
  48. }else if(DLL_PROCESS_ATTACH == ulReason){
  49. InitializeCriticalSection(&(CRequestObject::m_cs));
  50. InitializeCriticalSection(&(CGenericClass::m_cs));
  51. DisableThreadLibraryCalls(hInstance); // 158024
  52. try
  53. {
  54. //for this one we can't afford to throw on lock failure.
  55. retVal = InitializeCriticalSectionAndSpinCount(&g_msi_prov_cs, 0x80000000);
  56. }
  57. catch(...)
  58. {
  59. retVal = FALSE;
  60. }
  61. }
  62. return retVal;
  63. }
  64. //***************************************************************************
  65. //
  66. // DllGetClassObject
  67. //
  68. // Purpose: Called by Ole when some client wants a class factory. Return
  69. // one only if it is the sort of class this DLL supports.
  70. //
  71. //***************************************************************************
  72. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv)
  73. {
  74. HRESULT hr = 0;
  75. CProvFactory *pObj;
  76. if(CLSID_MSIprov!=rclsid) return E_FAIL;
  77. pObj = new CProvFactory();
  78. if(NULL == pObj) return E_OUTOFMEMORY;
  79. hr = pObj->QueryInterface(riid, ppv);
  80. if(FAILED(hr)) delete pObj;
  81. return hr;
  82. }
  83. //***************************************************************************
  84. //
  85. // DllCanUnloadNow
  86. //
  87. // Purpose: Called periodically by Ole in order to determine if the
  88. // DLL can be freed.
  89. //
  90. // Return: S_OK if there are no objects in use and the class factory
  91. // isn't locked.
  92. //
  93. //***************************************************************************
  94. STDAPI DllCanUnloadNow(void)
  95. {
  96. SCODE sc;
  97. //It is OK to unload if there are no objects or locks on the
  98. // class factory.
  99. sc = (0L == g_cObj && 0L == g_cLock) ? S_OK : S_FALSE;
  100. if ( sc == S_OK )
  101. {
  102. UnloadMsiDll();
  103. if ( g_wcpLoggingDir )
  104. {
  105. delete [] g_wcpLoggingDir;
  106. g_wcpLoggingDir = NULL;
  107. }
  108. }
  109. return sc;
  110. }
  111. BOOL IsLessThan4()
  112. {
  113. OSVERSIONINFO os;
  114. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  115. if(!GetVersionEx(&os))
  116. return FALSE; // should never happen
  117. return os.dwMajorVersion < 4;
  118. }
  119. //***************************************************************************
  120. //
  121. // DllRegisterServer
  122. //
  123. // Purpose: Called during setup or by regsvr32.
  124. //
  125. // Return: NOERROR if registration successful, error otherwise.
  126. //***************************************************************************
  127. STDAPI DllRegisterServer(void)
  128. {
  129. #ifndef UNICODE
  130. TCHAR szID[265];
  131. #else UNICODE
  132. TCHAR* szID = NULL;
  133. #endif UNICODE
  134. WCHAR wcID[265];
  135. TCHAR szCLSID[265];
  136. TCHAR szModule[MAX_PATH+1];
  137. TCHAR * pName = _T("WMI MSI Provider");
  138. TCHAR * pModel;
  139. HKEY hKey1, hKey2;
  140. ghModule = GetModuleHandle(_T("MSIPROV"));
  141. // Normally we want to use "Both" as the threading model since
  142. // the DLL is free threaded, but NT 3.51 Ole doesnt work unless
  143. // the model is "Aparment"
  144. if(IsLessThan4()) pModel = _T("Apartment");
  145. else pModel = _T("Both");
  146. // Create the path.
  147. StringFromGUID2(CLSID_MSIprov, wcID, 128);
  148. #ifndef UNICODE
  149. WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
  150. #else UNICODE
  151. szID = wcID;
  152. #endif UNICODE
  153. _tcscpy(szCLSID, _T("Software\\classes\\CLSID\\"));
  154. _tcscat(szCLSID, szID);
  155. #ifdef LOCALSERVER
  156. HKEY hKey;
  157. TCHAR szProviderCLSIDAppID[128];
  158. _tcscpy(szProviderCLSIDAppID, _T("SOFTWARE\\CLASSES\\APPID\\"));
  159. _tcscat(szProviderCLSIDAppID, szID);
  160. RegCreateKey(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID, &hKey);
  161. RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)pName, (_tcslen(pName)+1) * sizeof ( TCHAR ));
  162. CloseHandle(hKey);
  163. #endif
  164. RegCreateKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey1);
  165. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)pName, (_tcslen(pName)+1) * sizeof ( TCHAR ));
  166. // Create entries under CLSID
  167. #ifdef LOCALSERVER
  168. RegCreateKey(hKey1, _T("LocalServer32"), &hKey2);
  169. #else
  170. RegCreateKey(hKey1, _T("InprocServer32"), &hKey2);
  171. #endif
  172. szModule[MAX_PATH] = 0;
  173. GetModuleFileName(ghModule, szModule, MAX_PATH/*length in TCHARS*/);
  174. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule, (_tcslen(szModule)+1) * sizeof ( TCHAR ));
  175. RegSetValueEx(hKey2, _T("ThreadingModel"), 0, REG_SZ, (BYTE *)pModel, (_tcslen(pModel)+1) * sizeof ( TCHAR ));
  176. CloseHandle(hKey1);
  177. CloseHandle(hKey2);
  178. // load the MOF files for this component
  179. HRESULT hr = NOERROR;
  180. HINSTANCE hinstWbemupgd = LoadLibrary(L"wbemupgd.dll");
  181. if (hinstWbemupgd)
  182. {
  183. PFN_LOAD_MOF_FILES pfnLoadMofFiles = (PFN_LOAD_MOF_FILES) GetProcAddress(hinstWbemupgd, "LoadMofFiles"); // no wide version of GetProcAddress
  184. if (pfnLoadMofFiles)
  185. {
  186. wchar_t* wszComponentName = L"MSI Provider";
  187. const char* rgpszMofFilename[] =
  188. {
  189. "msi.mof",
  190. "msi.mfl",
  191. NULL
  192. };
  193. if (!pfnLoadMofFiles(wszComponentName, rgpszMofFilename))
  194. {
  195. hr = WBEM_E_FAILED;
  196. }
  197. }
  198. else
  199. {
  200. hr = HRESULT_FROM_WIN32(GetLastError());
  201. }
  202. FreeLibrary(hinstWbemupgd);
  203. }
  204. else
  205. {
  206. hr = HRESULT_FROM_WIN32(GetLastError());
  207. }
  208. return hr;
  209. }
  210. //***************************************************************************
  211. //
  212. // DllUnregisterServer
  213. //
  214. // Purpose: Called when it is time to remove the registry entries.
  215. //
  216. // Return: NOERROR if registration successful, error otherwise.
  217. //***************************************************************************
  218. STDAPI DllUnregisterServer(void)
  219. {
  220. WCHAR wcID[256];
  221. #ifndef UNICODE
  222. TCHAR szID[265];
  223. #else UNICODE
  224. TCHAR* szID = NULL;
  225. #endif UNICODE
  226. TCHAR wcCLSID[256];
  227. HKEY hKey;
  228. // Create the path using the CLSID
  229. StringFromGUID2(CLSID_MSIprov, wcID, 128);
  230. #ifndef UNICODE
  231. WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
  232. #else UNICODE
  233. szID = wcID;
  234. #endif UNICODE
  235. _tcscpy(wcCLSID, _T("Software\\classes\\CLSID\\"));
  236. _tcscat(wcCLSID, szID);
  237. #ifdef LOCALSERVER
  238. TCHAR szProviderCLSIDAppID[128];
  239. _tcscpy(szProviderCLSIDAppID, _T("SOFTWARE\\CLASSES\\APPID\\"));
  240. _tcscat(szProviderCLSIDAppID,wcCLSID);
  241. //Delete entries under APPID
  242. RegDeleteKey(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID);
  243. TCHAR szTemp[128];
  244. _tcscpy(szTemp, wcCLSID);
  245. _tcscat(szTemp,_T("\\"));
  246. _tcscat(szTemp,_T("LocalServer32"));
  247. RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  248. #endif
  249. // First delete the InProcServer subkey.
  250. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, wcCLSID, &hKey);
  251. if(dwRet == NO_ERROR){
  252. RegDeleteKey(hKey, _T("InprocServer32"));
  253. CloseHandle(hKey);
  254. }
  255. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\classes\\CLSID"), &hKey);
  256. if(dwRet == NO_ERROR){
  257. RegDeleteKey(hKey,szID);
  258. CloseHandle(hKey);
  259. }
  260. return NOERROR;
  261. }