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.

309 lines
8.2 KiB

  1. //***************************************************************************
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Module: WBEM MSI Instance provider method execution
  6. //
  7. // Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  8. //
  9. //***************************************************************************
  10. #include <initguid.h>
  11. #include <precomp.h>
  12. #include "classfac.h"
  13. #include "msimeth_i.c"
  14. HMODULE ghModule;
  15. //Count number of objects and number of locks.
  16. long g_cObj=0;
  17. long g_cLock=0;
  18. //***************************************************************************
  19. //
  20. // LibMain32
  21. //
  22. // Purpose: Entry point for DLL.
  23. //
  24. // Return: TRUE if OK.
  25. //
  26. //***************************************************************************
  27. BOOL WINAPI LibMain32(HINSTANCE hInstance, ULONG ulReason
  28. , LPVOID pvReserved)
  29. {
  30. if(DLL_PROCESS_ATTACH == ulReason)
  31. {
  32. DisableThreadLibraryCalls(hInstance); // 158024
  33. }
  34. return TRUE;
  35. }
  36. //***************************************************************************
  37. //
  38. // DllGetClassObject
  39. //
  40. // Purpose: Called by Ole when some client wants a class factory. Return
  41. // one only if it is the sort of class this DLL supports.
  42. //
  43. //***************************************************************************
  44. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv)
  45. {
  46. HRESULT hr = S_OK;
  47. CMethodsFactory *pObj = NULL;
  48. if((CLSID_MsiProductMethods != rclsid) &&
  49. (CLSID_MsiSoftwareFeatureMethods != rclsid))
  50. return E_FAIL;
  51. pObj = new CMethodsFactory();
  52. if(NULL == pObj) return E_OUTOFMEMORY;
  53. hr = pObj->QueryInterface(riid, ppv);
  54. if(FAILED(hr)) delete pObj;
  55. return hr;
  56. }
  57. //***************************************************************************
  58. //
  59. // DllCanUnloadNow
  60. //
  61. // Purpose: Called periodically by Ole in order to determine if the
  62. // DLL can be freed.
  63. //
  64. // Return: S_OK if there are no objects in use and the class factory
  65. // isn't locked.
  66. //
  67. //***************************************************************************
  68. STDAPI DllCanUnloadNow(void)
  69. {
  70. SCODE sc;
  71. //It is OK to unload if there are no objects or locks on the
  72. // class factory.
  73. sc = (0L == g_cObj && 0L == g_cLock) ? S_OK : S_FALSE;
  74. return sc;
  75. }
  76. //***************************************************************************
  77. //
  78. // Is4OrMore
  79. //
  80. // Returns true if win95 or any version of NT > 3.51
  81. //
  82. //***************************************************************************
  83. BOOL IsLessThan4()
  84. {
  85. OSVERSIONINFO os;
  86. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  87. if(!GetVersionEx(&os))
  88. return FALSE; // should never happen
  89. return os.dwMajorVersion < 4;
  90. }
  91. //***************************************************************************
  92. //
  93. // DllRegisterServer
  94. //
  95. // Purpose: Called during setup or by regsvr32.
  96. //
  97. // Return: NOERROR if registration successful, error otherwise.
  98. //***************************************************************************
  99. STDAPI DllRegisterServer(void)
  100. {
  101. char szID[265];
  102. WCHAR wcID[265];
  103. char szCLSID[265];
  104. char szModule[MAX_PATH];
  105. char * pName = "IMsiProductMethods";
  106. char * pModel;
  107. HKEY hKey, hKey1, hKey2;
  108. ghModule = GetModuleHandleA("MSIMETH");
  109. // Normally we want to use "Both" as the threading model since
  110. // the DLL is free threaded, but NT 3.51 Ole doesnt work unless
  111. // the model is "Aparment"
  112. if(IsLessThan4()) pModel = "Apartment";
  113. else pModel = "Both";
  114. //////////////////////////////////////
  115. // Product Methods Implementation
  116. // Create the path.
  117. StringFromGUID2(CLSID_MsiProductMethods, wcID, 128);
  118. WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
  119. strcpy(szCLSID, "Software\\classes\\CLSID\\");
  120. strcat(szCLSID, szID);
  121. char szProviderCLSIDAppID[128];
  122. strcpy(szProviderCLSIDAppID, "SOFTWARE\\CLASSES\\APPID\\");
  123. strcat(szProviderCLSIDAppID, szID);
  124. RegCreateKeyA(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID, &hKey);
  125. RegSetValueExA(hKey, NULL, 0, REG_SZ, (BYTE *)pName, (strlen(pName) * 2)+1);
  126. CloseHandle(hKey);
  127. RegCreateKeyA(HKEY_LOCAL_MACHINE, szCLSID, &hKey1);
  128. RegSetValueExA(hKey1, NULL, 0, REG_SZ, (BYTE *)pName, (strlen(pName) * 2)+1);
  129. // Create entries under CLSID
  130. RegCreateKeyA(hKey1, "LocalServer32", &hKey2);
  131. GetModuleFileNameA(ghModule, szModule, MAX_PATH);
  132. RegSetValueExA(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule, (strlen(szModule) * 2)+1);
  133. RegSetValueExA(hKey2, "ThreadingModel", 0, REG_SZ, (BYTE *)pModel, (strlen(pModel) * 2)+1);
  134. CloseHandle(hKey1);
  135. CloseHandle(hKey2);
  136. //////////////////////////////////////
  137. // Software Feature Methods Implementation
  138. pName = "IMsiSoftwareFeatureMethods";
  139. // Create the path.
  140. StringFromGUID2(CLSID_MsiSoftwareFeatureMethods, wcID, 128);
  141. WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
  142. strcpy(szCLSID, "Software\\classes\\CLSID\\");
  143. strcat(szCLSID, szID);
  144. strcpy(szProviderCLSIDAppID, "SOFTWARE\\CLASSES\\APPID\\");
  145. strcat(szProviderCLSIDAppID, szID);
  146. RegCreateKeyA(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID, &hKey);
  147. RegSetValueExA(hKey, NULL, 0, REG_SZ, (BYTE *)pName, (strlen(pName) * 2)+1);
  148. CloseHandle(hKey);
  149. RegCreateKeyA(HKEY_LOCAL_MACHINE, szCLSID, &hKey1);
  150. RegSetValueExA(hKey1, NULL, 0, REG_SZ, (BYTE *)pName, (strlen(pName) * 2)+1);
  151. // Create entries under CLSID
  152. RegCreateKeyA(hKey1, "LocalServer32", &hKey2);
  153. GetModuleFileNameA(ghModule, szModule, MAX_PATH);
  154. RegSetValueExA(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule, (strlen(szModule) * 2)+1);
  155. RegSetValueExA(hKey2, "ThreadingModel", 0, REG_SZ, (BYTE *)pModel, (strlen(pModel) * 2)+1);
  156. CloseHandle(hKey1);
  157. CloseHandle(hKey2);
  158. return NOERROR;
  159. }
  160. //***************************************************************************
  161. //
  162. // DllUnregisterServer
  163. //
  164. // Purpose: Called when it is time to remove the registry entries.
  165. //
  166. // Return: NOERROR if registration successful, error otherwise.
  167. //***************************************************************************
  168. STDAPI DllUnregisterServer(void)
  169. {
  170. WCHAR wcID[256];
  171. char szID[256];
  172. char wcCLSID[256];
  173. HKEY hKey;
  174. //////////////////////////////////////
  175. // Product Methods Implementation
  176. // Create the path.
  177. StringFromGUID2(CLSID_MsiProductMethods, wcID, 128);
  178. WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
  179. strcpy(wcCLSID, "Software\\classes\\CLSID\\");
  180. strcat(wcCLSID, szID);
  181. char szProviderCLSIDAppID[128];
  182. strcpy(szProviderCLSIDAppID, "SOFTWARE\\CLASSES\\APPID\\");
  183. strcat(szProviderCLSIDAppID,wcCLSID);
  184. //Delete entries under APPID
  185. RegDeleteKeyA(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID);
  186. char szTemp[128];
  187. strcpy(szTemp, wcCLSID);
  188. strcat(szTemp,"\\");
  189. strcat(szTemp,"LocalServer32");
  190. RegDeleteKeyA(HKEY_CLASSES_ROOT, szTemp);
  191. // First delete the InProcServer subkey.
  192. DWORD dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, wcCLSID, &hKey);
  193. if(dwRet == NO_ERROR){
  194. RegDeleteKeyA(hKey, "InprocServer32");
  195. CloseHandle(hKey);
  196. }
  197. dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\classes\\CLSID", &hKey);
  198. if(dwRet == NO_ERROR){
  199. RegDeleteKeyA(hKey,szID);
  200. CloseHandle(hKey);
  201. }
  202. //////////////////////////////////////
  203. // Software Feature Methods Implementation
  204. // Create the path.
  205. StringFromGUID2(CLSID_MsiSoftwareFeatureMethods, wcID, 128);
  206. WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcID, (-1), szID, 256, NULL, NULL);
  207. strcpy(wcCLSID, "Software\\classes\\CLSID\\");
  208. strcat(wcCLSID, szID);
  209. strcpy(szProviderCLSIDAppID, "SOFTWARE\\CLASSES\\APPID\\");
  210. strcat(szProviderCLSIDAppID,wcCLSID);
  211. //Delete entries under APPID
  212. RegDeleteKeyA(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID);
  213. strcpy(szTemp, wcCLSID);
  214. strcat(szTemp,"\\");
  215. strcat(szTemp,"LocalServer32");
  216. RegDeleteKeyA(HKEY_CLASSES_ROOT, szTemp);
  217. // First delete the InProcServer subkey.
  218. dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, wcCLSID, &hKey);
  219. if(dwRet == NO_ERROR){
  220. RegDeleteKeyA(hKey, "InprocServer32");
  221. CloseHandle(hKey);
  222. }
  223. dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\classes\\CLSID", &hKey);
  224. if(dwRet == NO_ERROR){
  225. RegDeleteKeyA(hKey,szID);
  226. CloseHandle(hKey);
  227. }
  228. return NOERROR;
  229. }