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.

403 lines
11 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. /* File: dskquota.cpp
  3. Description: Contains standard functions for an OLE component server DLL.
  4. DllMain
  5. DllGetClassObject
  6. DllCanUnloadNow
  7. Revision History:
  8. Date Description Programmer
  9. -------- --------------------------------------------------- ----------
  10. 05/22/96 Initial creation. BrianAu
  11. 12/10/96 Moved to free-threading OLE apartment model. BrianAu
  12. */
  13. ///////////////////////////////////////////////////////////////////////////////
  14. #include "pch.h" // PCH
  15. #pragma hdrstop
  16. #define INITGUIDS // Define GUIDs.
  17. #include "dskquota.h"
  18. #include "guidsp.h" // Private GUIDs.
  19. #include <gpedit.h> // For GUIDs.
  20. #include "factory.h" // Class factory declarations.
  21. #include "sidcache.h" // SID/Name cache.
  22. #include "registry.h"
  23. //
  24. // Verify that build is UNICODE.
  25. //
  26. #if !defined(UNICODE)
  27. # error This module must be compiled UNICODE.
  28. #endif
  29. HINSTANCE g_hInstDll = NULL; // DLL instance handle.
  30. LONG g_cRefThisDll = 0; // DLL reference count.
  31. LONG g_cLockThisDll = 0; // DLL lock count.
  32. ///////////////////////////////////////////////////////////////////////////////
  33. /* Function: DllGetClassObject
  34. Description: Creates instance of DiskQuotaControlClassFactory.
  35. Arguments:
  36. rclsid - Reference to class ID that identifies the type of object that the
  37. class factory will be asked to create.
  38. riid - Reference to interface ID on the class factory object.
  39. ppvOut - Destination location for class factory object pointer after
  40. instantiation.
  41. Returns:
  42. NOERROR - Success.
  43. E_OUTOFMEMORY - Can't create class factory object.
  44. E_NOINTERFACE - Interface not supported.
  45. E_INVALIDARG - ppvOut arg is NULL.
  46. CLASS_E_CLASSNOTAVAILABLE - Class factory not available.
  47. Revision History:
  48. Date Description Programmer
  49. -------- --------------------------------------------------- ----------
  50. 05/22/96 Initial creation. BrianAu
  51. */
  52. ///////////////////////////////////////////////////////////////////////////////
  53. STDAPI
  54. DllGetClassObject(
  55. REFCLSID rclsid,
  56. REFIID riid,
  57. LPVOID *ppvOut
  58. )
  59. {
  60. DBGTRACE((DM_COM, DL_HIGH, TEXT("DllGetClassObject")));
  61. DBGPRINTIID(DM_COM, DL_HIGH, (REFIID)rclsid);
  62. DBGPRINTIID(DM_COM, DL_HIGH, riid);
  63. HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
  64. if (NULL == ppvOut)
  65. return E_INVALIDARG;
  66. *ppvOut = NULL;
  67. try
  68. {
  69. if (IsEqualIID(rclsid, CLSID_DiskQuotaControl))
  70. {
  71. DiskQuotaControlClassFactory *pClassFactory = NULL;
  72. pClassFactory = new DiskQuotaControlClassFactory;
  73. hr = pClassFactory->QueryInterface(riid, ppvOut);
  74. if (FAILED(hr))
  75. {
  76. delete pClassFactory;
  77. }
  78. }
  79. }
  80. catch(CAllocException& e)
  81. {
  82. DBGERROR((TEXT("Insufficient memory exception")));
  83. hr = E_OUTOFMEMORY;
  84. }
  85. return hr;
  86. }
  87. ///////////////////////////////////////////////////////////////////////////////
  88. /* Function: DllCanUnloadNow
  89. Description: Called by OLE to determine if DLL can be unloaded.
  90. Arguments: None.
  91. Returns:
  92. S_FALSE - Can't unload. Ref count or lock count are > 0.
  93. S_OK - OK to unload. Ref count and lock count are 0.
  94. Revision History:
  95. Date Description Programmer
  96. -------- --------------------------------------------------- ----------
  97. 05/22/96 Initial creation. BrianAu
  98. */
  99. ///////////////////////////////////////////////////////////////////////////////
  100. STDAPI
  101. DllCanUnloadNow(
  102. VOID
  103. )
  104. {
  105. DBGTRACE((DM_COM, DL_HIGH, TEXT("DllCanUnloadNow")));
  106. DBGPRINT((DM_COM, DL_HIGH, TEXT("\tRefCnt = %d LockCnt = %d"),
  107. g_cRefThisDll, g_cLockThisDll));
  108. #ifdef DEBUG_PROCESS_DETACH
  109. //
  110. // This code will force the DLL to be unloaded so that we can
  111. // test OnProcessDetach(). Otherwise, OLE will wait 10 minutes
  112. // after DllCanUnloadNow returns S_OK to call FreeLibrary.
  113. // Note however that the process will AV when OLE finally gets
  114. // around to freeing the library. Therefore, we don't leave
  115. // this code active in free or check builds; only private debug
  116. // builds. Must explicitly define DEBUG_PROCESS_DETACH.
  117. //
  118. if (0 == g_cRefThisDll && 0 == g_cLockThisDll)
  119. {
  120. HINSTANCE hMod;
  121. static INT iExeThisPath = 0;
  122. if (0 == iExeThisPath++)
  123. {
  124. hMod = LoadLibrary(TEXT("dskquota.dll"));
  125. if (NULL != hMod)
  126. {
  127. DBGASSERT((g_hInstDll == hMod));
  128. FreeLibrary(hMod);
  129. FreeLibrary(hMod);
  130. }
  131. }
  132. }
  133. #endif // DEBUG_PROCESS_DETACH
  134. return (0 == g_cRefThisDll && 0 == g_cLockThisDll) ? S_OK : S_FALSE;
  135. }
  136. ///////////////////////////////////////////////////////////////////////////////
  137. /* Function: DllRegisterServer
  138. Description: Create the necessary registry entries for dskquota.dll
  139. to operate properly. This is called by REGSVR32.EXE.
  140. Arguments: None.
  141. Returns:
  142. S_OK - Succeeded.
  143. SELFREG_E_CLASS - Failed to create one of the registry entries.
  144. Revision History:
  145. Date Description Programmer
  146. -------- --------------------------------------------------- ----------
  147. 08/18/97 Initial creation. BrianAu
  148. */
  149. ///////////////////////////////////////////////////////////////////////////////
  150. HRESULT
  151. DllRegisterServer(
  152. VOID
  153. )
  154. {
  155. DBGTRACE((DM_COM, DL_HIGH, TEXT("DllRegisterServer")));
  156. HRESULT hr = CallRegInstall(g_hInstDll, "RegDll");
  157. if (FAILED(hr))
  158. {
  159. hr = SELFREG_E_CLASS;
  160. }
  161. return hr;
  162. }
  163. ///////////////////////////////////////////////////////////////////////////////
  164. /* Function: DllUnregisterServer
  165. Description: Remove the necessary registry entries for dskquota.dll.
  166. This is called by REGSVR32.EXE.
  167. Arguments: None.
  168. Returns:
  169. S_OK - Succeeded.
  170. SELFREG_E_CLASS - Failed to remove the CLSID entry.
  171. Revision History:
  172. Date Description Programmer
  173. -------- --------------------------------------------------- ----------
  174. 08/18/97 Initial creation. BrianAu
  175. */
  176. ///////////////////////////////////////////////////////////////////////////////
  177. HRESULT
  178. DllUnregisterServer(
  179. VOID
  180. )
  181. {
  182. DBGTRACE((DM_COM, DL_HIGH, TEXT("DllUnregisterServer")));
  183. HRESULT hr = CallRegInstall(g_hInstDll, "UnregDll");
  184. if (FAILED(hr))
  185. {
  186. hr = SELFREG_E_CLASS;
  187. }
  188. return hr;
  189. }
  190. ///////////////////////////////////////////////////////////////////////////////
  191. /* Function: OnProcessAttach
  192. Description: Handles all tasks associated with a process attaching to
  193. the DLL.
  194. Try to keep processing time to a minimum.
  195. Arguments:
  196. hInstDll - The DLL instance handle passed to DllMain.
  197. Returns:
  198. NOERROR - Success.
  199. E_FAIL - Something failed.
  200. Revision History:
  201. Date Description Programmer
  202. -------- --------------------------------------------------- ----------
  203. 08/09/96 Initial creation. BrianAu
  204. */
  205. ///////////////////////////////////////////////////////////////////////////////
  206. HRESULT
  207. OnProcessAttach(
  208. HINSTANCE hInstDll
  209. )
  210. {
  211. DBGTRACE((DM_COM, DL_HIGH, TEXT("OnProcessAttach")));
  212. HRESULT hr = NOERROR;
  213. //
  214. // Start IceCAP profiling.
  215. //
  216. ICAP_START_ALL;
  217. #if DBG
  218. DBGMODULE(TEXT("DSKQUOTA")); // Name of module displayed with messages.
  219. RegKey key(HKEY_LOCAL_MACHINE, REGSTR_KEY_DISKQUOTA);
  220. if (SUCCEEDED(key.Open(KEY_READ)))
  221. {
  222. DebugRegParams dp;
  223. if (SUCCEEDED(key.GetValue(REGSTR_VAL_DEBUGPARAMS, (LPBYTE)&dp, sizeof(dp))))
  224. {
  225. DBGPRINTMASK(dp.PrintMask);
  226. DBGPRINTLEVEL(dp.PrintLevel);
  227. DBGPRINTVERBOSE(dp.PrintVerbose);
  228. DBGTRACEMASK(dp.TraceMask);
  229. DBGTRACELEVEL(dp.TraceLevel);
  230. DBGTRACEVERBOSE(dp.TraceVerbose);
  231. DBGTRACEONEXIT(dp.TraceOnExit);
  232. }
  233. }
  234. #endif // DBG
  235. g_hInstDll = hInstDll;
  236. DisableThreadLibraryCalls(hInstDll);
  237. return hr;
  238. }
  239. ///////////////////////////////////////////////////////////////////////////////
  240. /* Function: OnProcessDetach
  241. Description: Handles all tasks associated with a process detaching from
  242. the DLL.
  243. Arguments: None.
  244. Returns:
  245. NOERROR - Success.
  246. Revision History:
  247. Date Description Programmer
  248. -------- --------------------------------------------------- ----------
  249. 08/09/96 Initial creation. BrianAu
  250. */
  251. ///////////////////////////////////////////////////////////////////////////////
  252. HRESULT
  253. OnProcessDetach(
  254. VOID
  255. )
  256. {
  257. DBGTRACE((DM_COM, DL_HIGH, TEXT("OnProcessAttach")));
  258. HRESULT hr = NOERROR;
  259. #ifdef DEBUG_PROCESS_DETACH
  260. LoadLibrary(TEXT("dskquota.dll"));
  261. #endif
  262. SidNameCache_Destroy();
  263. //
  264. // Stop IceCAP profiling.
  265. //
  266. ICAP_STOP_ALL;
  267. return hr;
  268. }
  269. ///////////////////////////////////////////////////////////////////////////////
  270. /* Function: DllMain
  271. Description: Main entry point for OLE component server.
  272. Arguments:
  273. hInstDll - Instance handle of DLL
  274. fdwReason - Reason DllMain is being called. Can be at Process attach/
  275. detach or Thread attach/detach.
  276. lpdwReserved - Reserved.
  277. Returns:
  278. TRUE - Successful initialization.
  279. FALSE - Failed initialization.
  280. Revision History:
  281. Date Description Programmer
  282. -------- --------------------------------------------------- ----------
  283. 05/22/96 Initial creation. BrianAu
  284. 08/09/96 Moved code associated with process attach and BrianAu
  285. detach out to separate functions.
  286. */
  287. ///////////////////////////////////////////////////////////////////////////////
  288. BOOL WINAPI
  289. DllMain(
  290. HINSTANCE hInstDll,
  291. DWORD fdwReason,
  292. LPVOID lpvReserved
  293. )
  294. {
  295. DBGTRACE((DM_COM, DL_HIGH, TEXT("DllMain")));
  296. BOOL bResult = FALSE;
  297. switch(fdwReason)
  298. {
  299. case DLL_PROCESS_ATTACH:
  300. DBGPRINT((DM_COM, DL_HIGH, TEXT("DLL_PROCESS_ATTACH")));
  301. bResult = SUCCEEDED(OnProcessAttach(hInstDll));
  302. break;
  303. case DLL_THREAD_ATTACH:
  304. case DLL_THREAD_DETACH:
  305. bResult = TRUE;
  306. break;
  307. case DLL_PROCESS_DETACH:
  308. DBGPRINT((DM_COM, DL_HIGH, TEXT("DLL_PROCESS_DETACH")));
  309. bResult = SUCCEEDED(OnProcessDetach());
  310. break;
  311. }
  312. return bResult;
  313. }