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.

488 lines
13 KiB

  1. //=--------------------------------------------------------------------------=
  2. // IPServer.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implements all exported DLL functions for the program, as well as a few
  13. // others that will be used by same
  14. //
  15. #include "IPServer.H"
  16. #include "LocalSrv.H"
  17. #include "AutoObj.H"
  18. #include "ClassF.H"
  19. #include "CtrlObj.H"
  20. #include "Globals.H"
  21. #include "Unknown.H"
  22. #include "Util.H"
  23. //=--------------------------------------------------------------------------=
  24. // Private module level data
  25. //
  26. // for ASSERT and FAIL
  27. //
  28. SZTHISFILE
  29. //=--------------------------------------------------------------------------=
  30. // These are used for reflection in OLE Controls. Not that big of a hit that
  31. // we mind defining them for all servers, including automation or generic
  32. // COM.
  33. //
  34. char g_szReflectClassName [] = "CtlFrameWork_ReflectWindow";
  35. BYTE g_fRegisteredReflect = FALSE;
  36. //=--------------------------------------------------------------------------=
  37. // allow controls to register for DLL_THREAD_ATTACH and DLL_THREAD_DETACH
  38. //
  39. THRDNFYPROC g_pfnThreadProc = NULL;
  40. extern "C" void SetLibraryThreadProc(THRDNFYPROC pfnThreadNotify)
  41. {
  42. if ((g_pfnThreadProc = pfnThreadNotify) == NULL)
  43. DisableThreadLibraryCalls((HMODULE)g_hInstance);
  44. }
  45. // ref count for LockServer
  46. //
  47. LONG g_cLocks;
  48. // private routines for this file.
  49. //
  50. int IndexOfOleObject(REFCLSID);
  51. HRESULT RegisterAllObjects(void);
  52. HRESULT UnregisterAllObjects(void);
  53. //=--------------------------------------------------------------------------=
  54. // DllMain
  55. //=--------------------------------------------------------------------------=
  56. // yon standard LibMain.
  57. //
  58. // Parameters and Output:
  59. // - see SDK Docs on DllMain
  60. //
  61. // Notes:
  62. //
  63. BOOL WINAPI DllMain
  64. (
  65. HANDLE hInstance,
  66. DWORD dwReason,
  67. void *pvReserved
  68. )
  69. {
  70. int i;
  71. switch (dwReason) {
  72. // set up some global variables, and get some OS/Version information
  73. // set up.
  74. //
  75. case DLL_PROCESS_ATTACH:
  76. {
  77. DWORD dwVer = GetVersion();
  78. DWORD dwWinVer;
  79. // swap the two lowest bytes of dwVer so that the major and minor version
  80. // numbers are in a usable order.
  81. // for dwWinVer: high byte = major version, low byte = minor version
  82. // OS Sys_WinVersion (as of 5/2/95)
  83. // =-------------= =-------------=
  84. // Win95 0x035F (3.95)
  85. // WinNT ProgMan 0x0333 (3.51)
  86. // WinNT Win95 UI 0x0400 (4.00)
  87. //
  88. dwWinVer = (UINT)(((dwVer & 0xFF) << 8) | ((dwVer >> 8) & 0xFF));
  89. g_fSysWinNT = FALSE;
  90. g_fSysWin95 = FALSE;
  91. g_fSysWin95Shell = FALSE;
  92. if (dwVer < 0x80000000) {
  93. g_fSysWinNT = TRUE;
  94. g_fSysWin95Shell = (dwWinVer >= 0x0334);
  95. } else {
  96. g_fSysWin95 = TRUE;
  97. g_fSysWin95Shell = TRUE;
  98. }
  99. // initialize a critical seciton for our apartment threading support
  100. //
  101. InitializeCriticalSection(&g_CriticalSection);
  102. // create an initial heap for everybody to use.
  103. // currently, we're going to let the system make things thread-safe,
  104. // which will make them a little slower, but hopefully not enough
  105. // to notice
  106. //
  107. g_hHeap = GetProcessHeap();
  108. if (!g_hHeap) {
  109. FAIL("Couldn't get Process Heap. Not good!");
  110. return FALSE;
  111. }
  112. g_hInstance = (HINSTANCE)hInstance;
  113. // give the user a chance to initialize whatever
  114. //
  115. InitializeLibrary();
  116. // if they didn't ask for thread notifications then optimize by turning
  117. // them off for our DLL.
  118. //
  119. if (!g_pfnThreadProc)
  120. DisableThreadLibraryCalls((HMODULE)hInstance);
  121. }
  122. break;
  123. case DLL_THREAD_ATTACH:
  124. case DLL_THREAD_DETACH:
  125. if (g_pfnThreadProc)
  126. g_pfnThreadProc(hInstance, dwReason, pvReserved);
  127. break;
  128. // do a little cleaning up!
  129. //
  130. case DLL_PROCESS_DETACH:
  131. // clean up our critical seciton
  132. //
  133. DeleteCriticalSection(&g_CriticalSection);
  134. // unregister all the registered window classes.
  135. //
  136. i = 0;
  137. while (!ISEMPTYOBJECT(i)) {
  138. if (g_ObjectInfo[i].usType == OI_CONTROL) {
  139. if (CTLWNDCLASSREGISTERED(i))
  140. UnregisterClass(WNDCLASSNAMEOFCONTROL(i), g_hInstance);
  141. }
  142. i++;
  143. }
  144. // clean up our parking window.
  145. //
  146. if (g_hwndParking) {
  147. DestroyWindow(g_hwndParking);
  148. UnregisterClass("CtlFrameWork_Parking", g_hInstance);
  149. --g_cLocks;
  150. }
  151. // clean up after reflection, if appropriate.
  152. //
  153. if (g_fRegisteredReflect)
  154. UnregisterClass(g_szReflectClassName, g_hInstance);
  155. // give the user a chance to do some cleaning up
  156. //
  157. UninitializeLibrary();
  158. break;
  159. }
  160. return TRUE;
  161. }
  162. //=--------------------------------------------------------------------------=
  163. // DllRegisterServer
  164. //=--------------------------------------------------------------------------=
  165. // registers the Automation server
  166. //
  167. // Output:
  168. // HRESULT
  169. //
  170. // Notes:
  171. //
  172. STDAPI DllRegisterServer
  173. (
  174. void
  175. )
  176. {
  177. HRESULT hr;
  178. hr = RegisterAllObjects();
  179. RETURN_ON_FAILURE(hr);
  180. // call user registration function.
  181. //
  182. return (RegisterData())? S_OK : E_FAIL;
  183. }
  184. //=--------------------------------------------------------------------------=
  185. // DllUnregisterServer
  186. //=--------------------------------------------------------------------------=
  187. // unregister's the Automation server
  188. //
  189. // Output:
  190. // HRESULT
  191. //
  192. // Notes:
  193. //
  194. STDAPI DllUnregisterServer
  195. (
  196. void
  197. )
  198. {
  199. HRESULT hr;
  200. hr = UnregisterAllObjects();
  201. RETURN_ON_FAILURE(hr);
  202. // call user unregistration function
  203. //
  204. return (UnregisterData()) ? S_OK : E_FAIL;
  205. }
  206. //=--------------------------------------------------------------------------=
  207. // DllCanUnloadNow
  208. //=--------------------------------------------------------------------------=
  209. // we are being asked whether or not it's okay to unload the DLL. just check
  210. // the lock counts on remaining objects ...
  211. //
  212. // Output:
  213. // HRESULT - S_OK, can unload now, S_FALSE, can't.
  214. //
  215. // Notes:
  216. //
  217. STDAPI DllCanUnloadNow
  218. (
  219. void
  220. )
  221. {
  222. // if there are any objects lying around, then we can't unload. The
  223. // controlling CUnknownObject class that people should be inheriting from
  224. // takes care of this
  225. //
  226. return (g_cLocks) ? S_FALSE : S_OK;
  227. }
  228. //=--------------------------------------------------------------------------=
  229. // DllGetClassObject
  230. //=--------------------------------------------------------------------------=
  231. // creates a ClassFactory object, and returns it.
  232. //
  233. // Parameters:
  234. // REFCLSID - CLSID for the class object
  235. // REFIID - interface we want class object to be.
  236. // void ** - pointer to where we should ptr to new object.
  237. //
  238. // Output:
  239. // HRESULT - S_OK, CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY,
  240. // E_INVALIDARG, E_UNEXPECTED
  241. //
  242. // Notes:
  243. //
  244. STDAPI DllGetClassObject
  245. (
  246. REFCLSID rclsid,
  247. REFIID riid,
  248. void **ppvObjOut
  249. )
  250. {
  251. HRESULT hr;
  252. void *pv;
  253. int iIndex;
  254. // arg checking
  255. //
  256. if (!ppvObjOut)
  257. return E_INVALIDARG;
  258. // first of all, make sure they're asking for something we work with.
  259. //
  260. iIndex = IndexOfOleObject(rclsid);
  261. if (iIndex == -1)
  262. return CLASS_E_CLASSNOTAVAILABLE;
  263. // create the blank object.
  264. //
  265. pv = (void *)new CClassFactory(iIndex);
  266. if (!pv)
  267. return E_OUTOFMEMORY;
  268. // QI for whatever the user has asked for.
  269. //
  270. hr = ((IUnknown *)pv)->QueryInterface(riid, ppvObjOut);
  271. ((IUnknown *)pv)->Release();
  272. return hr;
  273. }
  274. //=--------------------------------------------------------------------------=
  275. // IndexOfOleObject
  276. //=--------------------------------------------------------------------------=
  277. // returns the index in our global table of objects of the given CLSID. if
  278. // it's not a supported object, then we return -1
  279. //
  280. // Parameters:
  281. // REFCLSID - [in] duh.
  282. //
  283. // Output:
  284. // int - >= 0 is index into global table, -1 means not supported
  285. //
  286. // Notes:
  287. //
  288. int IndexOfOleObject
  289. (
  290. REFCLSID rclsid
  291. )
  292. {
  293. int x = 0;
  294. // an object is creatable if it's CLSID is in the table of all allowable object
  295. // types.
  296. //
  297. while (!ISEMPTYOBJECT(x)) {
  298. if (OBJECTISCREATABLE(x)) {
  299. if (rclsid == CLSIDOFOBJECT(x))
  300. return x;
  301. }
  302. x++;
  303. }
  304. return -1;
  305. }
  306. //=--------------------------------------------------------------------------=
  307. // RegisterAllObjects
  308. //=--------------------------------------------------------------------------=
  309. // registers all the objects for the given automation server.
  310. //
  311. // Parameters:
  312. // none
  313. //
  314. // Output:
  315. // HERSULT - S_OK, E_FAIL
  316. //
  317. // Notes:
  318. //
  319. HRESULT RegisterAllObjects
  320. (
  321. void
  322. )
  323. {
  324. ITypeLib *pTypeLib;
  325. HRESULT hr;
  326. DWORD dwPathLen;
  327. char szTmp[MAX_PATH];
  328. int x = 0;
  329. // loop through all of our creatable objects [those that have a clsid in
  330. // our global table] and register them.
  331. //
  332. while (!ISEMPTYOBJECT(x)) {
  333. if (!OBJECTISCREATABLE(x)) {
  334. x++;
  335. continue;
  336. }
  337. // depending on the object type, register different pieces of information
  338. //
  339. switch (g_ObjectInfo[x].usType) {
  340. // for both simple co-creatable objects and proeprty pages, do the same
  341. // thing
  342. //
  343. case OI_UNKNOWN:
  344. case OI_PROPERTYPAGE:
  345. RegisterUnknownObject(NAMEOFOBJECT(x), CLSIDOFOBJECT(x));
  346. break;
  347. case OI_AUTOMATION:
  348. RegisterAutomationObject(g_szLibName, NAMEOFOBJECT(x), VERSIONOFOBJECT(x),
  349. *g_pLibid, CLSIDOFOBJECT(x));
  350. break;
  351. case OI_CONTROL:
  352. RegisterControlObject(g_szLibName, NAMEOFOBJECT(x), VERSIONOFOBJECT(x),
  353. *g_pLibid, CLSIDOFOBJECT(x), OLEMISCFLAGSOFCONTROL(x),
  354. BITMAPIDOFCONTROL(x));
  355. break;
  356. }
  357. x++;
  358. }
  359. // Load and register our type library.
  360. //
  361. if (g_fServerHasTypeLibrary) {
  362. dwPathLen = GetModuleFileName(g_hInstance, szTmp, MAX_PATH);
  363. MAKE_WIDEPTR_FROMANSI(pwsz, szTmp);
  364. hr = LoadTypeLib(pwsz, &pTypeLib);
  365. RETURN_ON_FAILURE(hr);
  366. hr = RegisterTypeLib(pTypeLib, pwsz, NULL);
  367. pTypeLib->Release();
  368. RETURN_ON_FAILURE(hr);
  369. }
  370. return S_OK;
  371. }
  372. //=--------------------------------------------------------------------------=
  373. // UnregisterAllObjects
  374. //=--------------------------------------------------------------------------=
  375. // un-registers all the objects for the given automation server.
  376. //
  377. // Parameters:
  378. // none
  379. //
  380. // Output:
  381. // HRESULT - S_OK
  382. //
  383. // Notes:
  384. //
  385. HRESULT UnregisterAllObjects
  386. (
  387. void
  388. )
  389. {
  390. int x = 0;
  391. // loop through all of our creatable objects [those that have a clsid in
  392. // our global table] and register them.
  393. //
  394. while (!ISEMPTYOBJECT(x)) {
  395. if (!OBJECTISCREATABLE(x)) {
  396. x++;
  397. continue;
  398. }
  399. switch (g_ObjectInfo[x].usType) {
  400. case OI_UNKNOWN:
  401. case OI_PROPERTYPAGE:
  402. UnregisterUnknownObject(CLSIDOFOBJECT(x));
  403. break;
  404. case OI_CONTROL:
  405. UnregisterControlObject(g_szLibName, NAMEOFOBJECT(x), VERSIONOFOBJECT(x),
  406. CLSIDOFOBJECT(x));
  407. case OI_AUTOMATION:
  408. UnregisterAutomationObject(g_szLibName, NAMEOFOBJECT(x), VERSIONOFOBJECT(x),
  409. CLSIDOFOBJECT(x));
  410. break;
  411. }
  412. x++;
  413. }
  414. // if we've got one, unregister our type library [this isn't an API function
  415. // -- we've implemented this ourselves]
  416. //
  417. if (g_pLibid)
  418. UnregisterTypeLibrary(*g_pLibid);
  419. return S_OK;
  420. }