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.

352 lines
10 KiB

  1. //---------------------------------------------------------------------------
  2. // MSR2C.cpp : implements DllMain
  3. //
  4. // Copyright (c) 1996 Microsoft Corporation, All Rights Reserved
  5. // Developed by Sheridan Software Systems, Inc.
  6. //---------------------------------------------------------------------------
  7. #include "stdafx.h"
  8. #include "MSR2C.h"
  9. #include "CMSR2C.h"
  10. #include "clssfcty.h"
  11. #include <mbstring.h>
  12. SZTHISFILE
  13. // DllMain
  14. //
  15. BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpvReserved)
  16. {
  17. switch (dwReason)
  18. {
  19. case DLL_PROCESS_ATTACH:
  20. return VDInitGlobals(hinstDll);
  21. case DLL_THREAD_ATTACH:
  22. case DLL_THREAD_DETACH:
  23. break;
  24. case DLL_PROCESS_DETACH:
  25. VDReleaseGlobals();
  26. break;
  27. }
  28. return TRUE;
  29. }
  30. ////////////////////////////////////////////////////////////////////
  31. // Name: DllGetClassObject
  32. // Desc: provides an IClassFactory for a given CLSID that this DLL
  33. // is registered to support. This DLL is placed under the
  34. // CLSID in the registration database as the InProcServer.
  35. // Parms: rclsid - identifies the class factory desired. since the
  36. // 'this' parameter is passed, this DLL can handle any
  37. // number of objects simply by returning different class
  38. // factories here for different CLSIDs.
  39. // riid - ID specifying the interface the caller wants on
  40. // the class object, usually IID_ClassFactory.
  41. // ppv - pointer in which to return the interface pointer.
  42. // Return: HRESULT - NOERROR on success, otherwise an error code.
  43. ////////////////////////////////////////////////////////////////////
  44. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void ** ppv)
  45. {
  46. HRESULT hr;
  47. CClassFactory *pObj;
  48. if (CLSID_CCursorFromRowset!=rclsid)
  49. return ResultFromScode(E_FAIL);
  50. pObj=new CClassFactory();
  51. if (NULL==pObj)
  52. return ResultFromScode(E_OUTOFMEMORY);
  53. hr=pObj->QueryInterface(riid, ppv);
  54. if (FAILED(hr))
  55. delete pObj;
  56. return hr;
  57. }
  58. ////////////////////////////////////////////////////////////////////
  59. // Name: DllCanUnloadNow
  60. // Desc: lets the client know if this DLL can be freed, ie if
  61. // there are no references to anything this DLL provides.
  62. // Parms: none
  63. // Return: TRUE if nothing is using us, FALSE otherwise.
  64. ////////////////////////////////////////////////////////////////////
  65. STDAPI DllCanUnloadNow(void)
  66. {
  67. SCODE sc;
  68. //Our answer is whether there are any object or locks
  69. EnterCriticalSection(&g_CriticalSection);
  70. sc=(0L==g_cObjectCount && 0L==g_cLockCount) ? S_OK : S_FALSE;
  71. LeaveCriticalSection(&g_CriticalSection);
  72. return ResultFromScode(sc);
  73. }
  74. ////////////////////////////////////////////////////////////////////
  75. // Name: CSSCFcty
  76. // Desc: constructor
  77. // Parms: none
  78. // Return: none
  79. ////////////////////////////////////////////////////////////////////
  80. CClassFactory::CClassFactory(void)
  81. {
  82. m_cRef=0L;
  83. return;
  84. }
  85. ////////////////////////////////////////////////////////////////////
  86. // Name: ~CClassFactory
  87. // Desc: destructor
  88. // Parms: none
  89. // Return: none
  90. ////////////////////////////////////////////////////////////////////
  91. CClassFactory::~CClassFactory(void)
  92. {
  93. return;
  94. }
  95. ////////////////////////////////////////////////////////////////////
  96. // Name: QueryInterface
  97. // Desc: queries the class factory for a method.
  98. // Parms: riid -
  99. // ppv -
  100. // Return: HRESULT - NOERROR if successful, otherwise an error code.
  101. ////////////////////////////////////////////////////////////////////
  102. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID * ppv)
  103. {
  104. *ppv=NULL;
  105. if (IID_IUnknown==riid || IID_IClassFactory==riid)
  106. *ppv=this;
  107. if (NULL!=*ppv)
  108. {
  109. ((LPUNKNOWN)*ppv)->AddRef();
  110. return NOERROR;
  111. }
  112. return ResultFromScode(E_NOINTERFACE);
  113. }
  114. ////////////////////////////////////////////////////////////////////
  115. // Name: AddRef
  116. // Desc: incrementes the class factory object reference count.
  117. // Parms: none
  118. // Return: current reference count.
  119. ////////////////////////////////////////////////////////////////////
  120. STDMETHODIMP_(ULONG) CClassFactory::AddRef(void)
  121. {
  122. return ++m_cRef;
  123. }
  124. ////////////////////////////////////////////////////////////////////
  125. // Name: Release
  126. // Desc: decrement the reference count on the class factory. If
  127. // the count has gone to 0, destroy the object.
  128. // Parms: none
  129. // Return: current reference count.
  130. ////////////////////////////////////////////////////////////////////
  131. STDMETHODIMP_(ULONG) CClassFactory::Release(void)
  132. {
  133. // if ref count can be decremented, return count
  134. if (0L!=--m_cRef)
  135. return m_cRef;
  136. // delete this object
  137. delete this;
  138. return 0L;
  139. }
  140. ////////////////////////////////////////////////////////////////////
  141. // Name: CreateInstance
  142. // Desc: instantiates an CVDCursorFromRowset object, returning an interface
  143. // pointer.
  144. // Parms: riid - ID identifying the interface the caller
  145. // desires to have for the new object.
  146. // ppvObj - pointer in which to store the desired
  147. // interface pointer for the new object.
  148. // Return: HRESULT - NOERROR if successful, otherwise
  149. // E_NOINTERFACE if we cannot support the
  150. // requested interface.
  151. ////////////////////////////////////////////////////////////////////
  152. STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj)
  153. {
  154. return CVDCursorFromRowset::CreateInstance(pUnkOuter, riid, ppvObj);
  155. }
  156. ////////////////////////////////////////////////////////////////////
  157. // Name: LockServer
  158. // Desc: increments or decrements the lock count of the DLL. if
  159. // the lock count goes to zero, and there are no objects,
  160. // the DLL is allowed to unload.
  161. // Parms: fLock - boolean specifies whether to increment or
  162. // decrement the lock count.
  163. // Return: HRESULT: NOERROR always.
  164. ////////////////////////////////////////////////////////////////////
  165. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  166. {
  167. EnterCriticalSection(&g_CriticalSection);
  168. if (fLock)
  169. {
  170. g_cLockCount++;
  171. }
  172. else
  173. {
  174. g_cLockCount--;
  175. }
  176. LeaveCriticalSection(&g_CriticalSection);
  177. return NOERROR;
  178. }
  179. ////////////////////////////////////////////////////////////////////
  180. // Name: DllRegisterServer
  181. // Desc: instructs the server to create its own registry entries.
  182. // all entries are put in the HKEY_CLASSES_ROOT.
  183. // Parms: none
  184. // Return: HRESULT - NOERROR if registration is successful, error
  185. // otherwise.
  186. ////////////////////////////////////////////////////////////////////
  187. STDAPI DllRegisterServer(void)
  188. {
  189. OLECHAR szID[128 * 2];
  190. TCHAR szTID[128 * 2];
  191. TCHAR szCLSID[128 * 2];
  192. TCHAR szModule[512 * 2];
  193. // put the guid in the form of a string with class id prefix
  194. StringFromGUID2(CLSID_CCursorFromRowset, szID, 128 * 2);
  195. WideCharToMultiByte(CP_ACP, 0, szID, -1, szTID, 128 * 2, NULL, NULL);
  196. _mbscpy((TBYTE*)szCLSID, (TBYTE*)TEXT("CLSID\\"));
  197. _mbscat((TBYTE*)szCLSID, (TBYTE*)szTID);
  198. SetKeyAndValue(szCLSID, NULL, NULL, NULL);
  199. GetModuleFileName(g_hinstance, szModule, sizeof(szModule)/sizeof(TCHAR));
  200. SetKeyAndValue(szCLSID, TEXT("InprocServer32"), szModule, TEXT("Apartment"));
  201. return S_OK;
  202. }
  203. ////////////////////////////////////////////////////////////////////
  204. // Name: DllUnregisterServer
  205. // Desc: instructs the server to remove its own registry entries.
  206. // Parms: none
  207. // Return: HRESULT: NOERROR if unregistration is successful, error
  208. // otherwise.
  209. ////////////////////////////////////////////////////////////////////
  210. STDAPI DllUnregisterServer(void)
  211. {
  212. OLECHAR szID[128 * 2];
  213. TCHAR szTID[128 * 2];
  214. TCHAR szCLSID[128 * 2];
  215. TCHAR szCLSIDInproc[128 * 2];
  216. // put the guid in the form of a string with class id prefix
  217. StringFromGUID2(CLSID_CCursorFromRowset, szID, 128 * 2);
  218. WideCharToMultiByte(CP_ACP, 0, szID, -1, szTID, 128 * 2, NULL, NULL);
  219. _mbscpy((TBYTE*)szCLSID, (TBYTE*)TEXT("CLSID\\"));
  220. _mbscat((TBYTE*)szCLSID, (TBYTE*)szTID);
  221. _mbscpy((TBYTE*)szCLSIDInproc, (TBYTE*)szCLSID);
  222. _mbscat((TBYTE*)szCLSIDInproc, (TBYTE*)TEXT("\\InprocServer32"));
  223. // delete the InprocServer32 key
  224. RegDeleteKey(HKEY_CLASSES_ROOT, szCLSIDInproc);
  225. // delete the class ID key
  226. RegDeleteKey(HKEY_CLASSES_ROOT, szCLSID);
  227. return S_OK;
  228. }
  229. ////////////////////////////////////////////////////////////////////
  230. // Name: SetKeyAndValue
  231. // Desc: creates a registry key, sets a value, and closes the key.
  232. // Parms: pszKey - pointer to a registry key.
  233. // pszSubkey - pointer to a registry subkey.
  234. // pszValue - pointer to value to enter for key-subkey
  235. // pszThreadingModel - pointer to threading model literal (optional)
  236. // Return: BOOL - TRUE if successful, FALSE otherwise.
  237. ////////////////////////////////////////////////////////////////////
  238. BOOL SetKeyAndValue(LPTSTR pszKey, LPTSTR pszSubkey, LPTSTR pszValue, LPTSTR pszThreadingModel)
  239. {
  240. HKEY hKey;
  241. TCHAR szKey[256 * 2];
  242. _mbscpy((TBYTE*)szKey, (TBYTE*)pszKey);
  243. if (NULL!=pszSubkey)
  244. {
  245. _mbscat((TBYTE*)szKey, (TBYTE*)TEXT("\\"));
  246. _mbscat((TBYTE*)szKey, (TBYTE*)pszSubkey);
  247. }
  248. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  249. szKey,
  250. 0,
  251. NULL,
  252. REG_OPTION_NON_VOLATILE,
  253. KEY_ALL_ACCESS,
  254. NULL,
  255. &hKey,
  256. NULL))
  257. return FALSE;
  258. if (NULL!=pszValue)
  259. {
  260. RegSetValueEx( hKey,
  261. NULL,
  262. 0,
  263. REG_SZ,
  264. (BYTE *)pszValue,
  265. _mbsnbcnt((TBYTE*)pszValue, (ULONG)-1) + 1);
  266. }
  267. if (NULL!=pszThreadingModel)
  268. {
  269. RegSetValueEx( hKey,
  270. TEXT("ThreadingModel"),
  271. 0,
  272. REG_SZ,
  273. (BYTE *)pszThreadingModel,
  274. _mbsnbcnt((TBYTE*)pszThreadingModel, (ULONG)-1) + 1);
  275. }
  276. RegCloseKey(hKey);
  277. return TRUE;
  278. }
  279. //=--------------------------------------------------------------------------=
  280. // CRT stubs
  281. //=--------------------------------------------------------------------------=
  282. // these two things are here so the CRTs aren't needed. this is good.
  283. //
  284. // basically, the CRTs define this to take in a bunch of stuff. we'll just
  285. // define them here so we don't get an unresolved external.
  286. //
  287. // TODO: if you are going to use the CRTs, then remove this line.
  288. //
  289. //extern "C" int __cdecl _fltused = 1;
  290. extern "C" int _cdecl _purecall(void)
  291. {
  292. FAIL("Pure virtual function called.");
  293. return 0;
  294. }