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.

792 lines
24 KiB

  1. // Copyright (C) 1996-1997 Microsoft Corporation. All rights reserved.
  2. //
  3. // implements all exported DLL functions for the program, as well as a few
  4. // others that will be used by same
  5. //
  6. #include "header.h"
  7. #include "internet.h"
  8. #include "AutoObj.H"
  9. #include "ClassF.H"
  10. #include "Unknown.H"
  11. #include "strtable.h"
  12. #include "hhifc.h"
  13. #include "hhsort.h"
  14. #include "resource.h"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static const char THIS_FILE[] = __FILE__;
  18. #endif
  19. #include "atlinc.h" // includes for ATL.
  20. #include "iterror.h"
  21. #include "itSort.h"
  22. #include "itSortid.h"
  23. #include "hhsyssrt.h"
  24. #include "hhfinder.h"
  25. #include "msitstg.h"
  26. // Only including for the pahwnd declaration.
  27. #include "secwin.h"
  28. // So we can cleanup the lasterror object.
  29. #include "lasterr.h"
  30. #include <atlimpl.cpp>
  31. extern HMODULE g_hmodMSI; // msi.dll module handle
  32. CHtmlHelpModule _Module;
  33. BEGIN_OBJECT_MAP(ObjectMap)
  34. OBJECT_ENTRY(CLSID_HHSysSort, CHHSysSort)
  35. OBJECT_ENTRY(CLSID_HHFinder, CHHFinder)
  36. END_OBJECT_MAP()
  37. const IID IID_ICatRegister = {0x0002E012,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  38. const GUID CATID_SafeForScripting = {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
  39. const GUID CATID_SafeForInitializing = {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
  40. // In 1996-1997 alone, these two constants appeared and disappeared in 3 different
  41. // header files. I got tired or finding out which !@$! header file they
  42. // got moved to this time and just defined them here.
  43. #define LANG_ARABIC 0x01
  44. #define LANG_HEBREW 0x0d
  45. static const char txtCplDesktop[] = "Control Panel\\Desktop\\ResourceLocale";
  46. static const char txtShellOpenFmt[] = "%s\\shell\\open\\%s";
  47. static const char txtCommand[] = "command";
  48. static const char txtStdOpen[] = "[open(\"%1\")]";
  49. static const char txtStdArg[] = " %1";
  50. static const char txtChmFile[] = "chm.file";
  51. static const char txtHhExe[] = "hh.exe";
  52. static const char txtItssDll[] = "itss.dll";
  53. static const char txtItirclDll[] = "itircl.dll";
  54. static const char txtDllRegisterServer[] = "DllRegisterServer";
  55. static const char txtDllUnRegisterServer[] = "DllUnregisterServer";
  56. static const char txtIE4[] = "SOFTWARE\\Microsoft\\Internet Explorer";
  57. static const char txtVersion[] = "version";
  58. static const char txtMouseWheel[] = "MSWHEEL_ROLLMSG";
  59. static const char txtStringGuid[] = "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}";
  60. static const char txtInProc[] = "CLSID\\%s\\InprocServer32";
  61. static void SetRegKey(LPCTSTR pszKey, LPCTSTR pszValue);
  62. void RegisterHH(PCSTR pszHHPath); // also called by hh.cpp
  63. extern HANDLE g_hsemMemory;
  64. //=--------------------------------------------------------------------------=
  65. // private routines for this file.
  66. int IndexOfOleObject(REFCLSID);
  67. HRESULT RegisterAllObjects(void);
  68. HRESULT UnregisterAllObjects(void);
  69. //=--------------------------------------------------------------------------=
  70. // StringFromGuidA
  71. //=--------------------------------------------------------------------------=
  72. // returns an ANSI string from a CLSID or GUID
  73. //
  74. // Parameters:
  75. // REFIID - [in] clsid to make string out of.
  76. // LPSTR - [in/out] buffer in which to place resultant GUID.
  77. //
  78. // Output:
  79. // int - number of chars written out.
  80. //
  81. // Notes:
  82. //
  83. int StringFromGuidA( CLSID riid, LPSTR pszBuf )
  84. {
  85. return wsprintf( (char*) pszBuf,
  86. txtStringGuid,
  87. riid.Data1, riid.Data2, riid.Data3,
  88. riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3],
  89. riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7]);
  90. }
  91. #define GUID_STR_LEN 40
  92. //=--------------------------------------------------------------------------=
  93. // GetRegisteredLocation
  94. //=--------------------------------------------------------------------------=
  95. // Returns the registered location of an inproc server given the CLSID
  96. //
  97. // HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 = <path to local server>
  98. //
  99. // Parameters:
  100. // REFCLSID - [in] CLSID of the object
  101. // LPTSTR - [in/out] Pathname
  102. //
  103. // Output:
  104. // BOOL - FALSE means couldn't find it
  105. BOOL GetRegisteredLocation( CLSID riid, LPTSTR pszPathname )
  106. {
  107. BOOL bReturn = FALSE;
  108. HKEY hKey = NULL;
  109. char szGuidStr[GUID_STR_LEN];
  110. char szScratch[MAX_PATH];
  111. if( !StringFromGuidA( riid, szGuidStr ) )
  112. return FALSE;
  113. wsprintf( szScratch, txtInProc, szGuidStr );
  114. if( RegOpenKeyEx( HKEY_CLASSES_ROOT, szScratch, 0, KEY_READ, &hKey ) == ERROR_SUCCESS ) {
  115. DWORD dwSize = MAX_PATH;
  116. if( RegQueryValueExA( hKey, "", 0, 0, (BYTE*) szScratch, &dwSize ) == ERROR_SUCCESS ) {
  117. strcpy( pszPathname, szScratch );
  118. bReturn = TRUE;
  119. }
  120. }
  121. if( hKey )
  122. RegCloseKey( hKey );
  123. return bReturn;
  124. }
  125. BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, void *pvReserved)
  126. {
  127. int i;
  128. switch (dwReason) {
  129. // set up some global variables, and get some OS/Version information
  130. // set up.
  131. //
  132. case DLL_PROCESS_ATTACH:
  133. {
  134. //NOTE: Do not handle resources until after the _Module.Init call below.
  135. OSVERSIONINFO versionInfo;
  136. versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  137. GetVersionEx(&versionInfo);
  138. g_bWinNT5 = ((versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && (versionInfo.dwMajorVersion >= 5));
  139. g_bWin98 = (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && ((versionInfo.dwMajorVersion > 4)
  140. || ((versionInfo.dwMajorVersion == 4) && (versionInfo.dwMinorVersion > 0)));
  141. // Check version
  142. DWORD dwVer = GetVersion();
  143. DWORD dwWinVer;
  144. // swap the two lowest bytes of dwVer so that the major and minor version
  145. // numbers are in a usable order.
  146. // for dwWinVer: high byte = major version, low byte = minor version
  147. // OS Sys_WinVersion (as of 5/2/95)
  148. // =-------------= =-------------=
  149. // Win95 0x035F (3.95)
  150. // WinNT ProgMan 0x0333 (3.51)
  151. // WinNT Win95 UI 0x0400 (4.00)
  152. //
  153. dwWinVer = (UINT)(((dwVer & 0xFF) << 8) | ((dwVer >> 8) & 0xFF));
  154. g_fSysWinNT = FALSE;
  155. g_fSysWin95 = FALSE;
  156. g_fSysWin95Shell = FALSE;
  157. if (dwVer < 0x80000000) {
  158. g_fSysWinNT = TRUE;
  159. g_fSysWin95Shell = (dwWinVer >= 0x0334);
  160. } else {
  161. g_fSysWin95 = TRUE;
  162. g_fSysWin95Shell = TRUE;
  163. }
  164. if ( !g_fCoInitialized )
  165. {
  166. OleInitialize(NULL);
  167. g_fCoInitialized = TRUE; // so that we call CoUninitialize() when dll is unloaded
  168. }
  169. // Initialize ATL's module information.
  170. _Module.Init(ObjectMap, (HINSTANCE) hInstance);
  171. DisableThreadLibraryCalls((HINSTANCE) hInstance);
  172. // Now it is okay to read the resources.
  173. g_fDBCSSystem = (BOOL) GetSystemMetrics(SM_DBCSENABLED);
  174. g_lcidSystem = GetUserDefaultLCID();
  175. // Determine if we are on a BiDi system
  176. g_langSystem = PRIMARYLANGID(LANGIDFROMLCID(g_lcidSystem));
  177. // Get the language of the UI (Satalite DLL)
  178. //
  179. LANGID lid = PRIMARYLANGID(_Module.m_Language.GetUiLanguage());
  180. // determine if we are running with a localized Hebrew or Arabic UI
  181. //
  182. if(lid == LANG_ARABIC || lid == LANG_HEBREW)
  183. g_bBiDiUi=TRUE;
  184. else
  185. g_bBiDiUi=FALSE;
  186. // determine if we are running with a localized Hebrew or Arabic UI
  187. //
  188. if(lid == LANG_ARABIC)
  189. g_bArabicUi=TRUE;
  190. else
  191. g_bArabicUi=FALSE;
  192. MSG_MOUSEWHEEL = RegisterWindowMessage(txtMouseWheel);
  193. // Find out if we are on IE 4 or later
  194. {
  195. HKEY hkey;
  196. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, txtIE4, 0, KEY_READ, &hkey) ==
  197. ERROR_SUCCESS) {
  198. char szVersion[MAX_PATH];
  199. DWORD cbPath = sizeof(szVersion);
  200. if (RegQueryValueEx(hkey, txtVersion, NULL, NULL, (LPBYTE) szVersion, &cbPath) == ERROR_SUCCESS) {
  201. // IE 3 didn't have a version key, so if this succeeds,
  202. // we know we aren't on IE 3.
  203. g_fIE3 = FALSE; // we're on IE 4, not IE 3
  204. g_bMsItsMonikerSupport = FALSE; // Don't make this TRUE. See bug 6984 & 6876
  205. }
  206. RegCloseKey(hkey);
  207. }
  208. }
  209. // register our server if the pathname is not the same as the
  210. // one that is already registered
  211. TCHAR szHHCtrl[MAX_PATH];
  212. szHHCtrl[0] = 0;
  213. TCHAR szModulePathname[MAX_PATH];
  214. szModulePathname[0] = 0;
  215. BOOL bRegister = FALSE;
  216. bRegister = !GetRegisteredLocation( CLSID_HHCtrl, szHHCtrl );
  217. if( !bRegister ) {
  218. GetModuleFileName( _Module.GetModuleInstance(), szModulePathname, MAX_PATH );
  219. if( lstrcmpi( szHHCtrl, szModulePathname ) != 0 )
  220. bRegister = TRUE;
  221. }
  222. if( bRegister )
  223. DllRegisterServer();
  224. // TODO: pahwnd needs to be incapsulated into a class and allocated on demand.
  225. g_cWindowSlots = 5;
  226. pahwnd = (CHHWinType**) lcCalloc(g_cWindowSlots * sizeof(CHHWinType*));
  227. memset( pahwnd, 0, g_cWindowSlots * sizeof(CHHWinType*) );
  228. return TRUE;
  229. }
  230. case DLL_PROCESS_DETACH:
  231. // DBWIN("HHCtrl unloading");
  232. // DeleteCriticalSection(&g_CriticalSection);
  233. // unregister all the registered window classes.
  234. // Clean out the memory in the last error object, since the heap is screwed before the destructor is called.
  235. g_LastError.Finish() ;
  236. i = 0;
  237. while (!ISEMPTYOBJECT(i)) {
  238. if (g_ObjectInfo[i].usType == OI_CONTROL) {
  239. #ifdef _DEBUG
  240. CONTROLOBJECTINFO* pinfo = (CONTROLOBJECTINFO*) g_ObjectInfo[i].pInfo;
  241. #endif
  242. if (CTLWNDCLASSREGISTERED(i))
  243. UnregisterClass(WNDCLASSNAMEOFCONTROL(i), _Module.GetModuleInstance());
  244. }
  245. i++;
  246. }
  247. // clean up our parking window.
  248. if (g_hwndParking) {
  249. DestroyWindow(g_hwndParking);
  250. UnregisterClass("CtlFrameWork_Parking", _Module.GetModuleInstance());
  251. --g_cLocks;
  252. }
  253. // free our window types list
  254. for( int i = 0; i < g_cWindowSlots; i++ )
  255. if( pahwnd[i] ) {
  256. CHECK_AND_FREE( pahwnd[i]->pszType );
  257. CHECK_AND_FREE( pahwnd[i]->pszCaption );
  258. CHECK_AND_FREE( pahwnd[i]->pszToc );
  259. CHECK_AND_FREE( pahwnd[i]->pszIndex );
  260. CHECK_AND_FREE( pahwnd[i]->pszFile );
  261. CHECK_AND_FREE( pahwnd[i]->pszHome );
  262. CHECK_AND_FREE( pahwnd[i]->pszJump1 );
  263. CHECK_AND_FREE( pahwnd[i]->pszJump2 );
  264. CHECK_AND_FREE( pahwnd[i]->pszUrlJump1 );
  265. CHECK_AND_FREE( pahwnd[i]->pszUrlJump2 );
  266. CHECK_AND_FREE( pahwnd[i]->pszCustomTabs );
  267. pahwnd[i]->ProcessDetachSafeCleanup();
  268. }
  269. CHECK_AND_FREE( pahwnd );
  270. // free the CHmData
  271. CHECK_AND_FREE( g_phmData );
  272. // don't call DBWIN here since it will cause a GPF
  273. if (g_hmodMSI != NULL)
  274. FreeLibrary(g_hmodMSI);
  275. if (g_hpalSplash)
  276. DeleteObject(g_hpalSplash);
  277. _Module.Term();
  278. if (g_hsemMemory)
  279. CloseHandle(g_hsemMemory);
  280. if (g_hsemNavigate)
  281. CloseHandle(g_hsemNavigate);
  282. // DeleteAllHmData();
  283. if (g_hmodHHA != NULL)
  284. {
  285. FreeLibrary(g_hmodHHA);
  286. g_hmodHHA = NULL;
  287. }
  288. if (g_fCoInitialized)
  289. {
  290. OleUninitialize();
  291. g_fCoInitialized = FALSE;
  292. }
  293. return TRUE;
  294. }
  295. return TRUE;
  296. }
  297. #ifndef HHUTIL
  298. //=--------------------------------------------------------------------------=
  299. // DllRegisterServer
  300. //=--------------------------------------------------------------------------=
  301. // registers the Automation server
  302. STDAPI DllRegisterServer(void)
  303. {
  304. HRESULT hr;
  305. hr = RegisterAllObjects();
  306. ASSERT(SUCCEEDED(hr));
  307. RETURN_ON_FAILURE(hr);
  308. CreateComponentCategory(CATID_SafeForScripting, L"Controls that are safely scriptable");
  309. CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data");
  310. RegisterCLSIDInCategory(CLSID_HHCtrl, CATID_SafeForScripting);
  311. RegisterCLSIDInCategory(CLSID_HHCtrl, CATID_SafeForInitializing);
  312. char szPath[MAX_PATH];
  313. GetRegWindowsDirectory(szPath);
  314. AddTrailingBackslash(szPath);
  315. strcat(szPath, txtHhExe);
  316. if (GetFileAttributes(szPath) != HFILE_ERROR)
  317. RegisterHH(szPath);
  318. GetSystemDirectory(szPath, sizeof(szPath));
  319. AddTrailingBackslash(szPath);
  320. PSTR pszEnd = szPath + strlen(szPath);
  321. strcpy(pszEnd, txtItssDll);
  322. // Register decompression DLL (for .CHM files)
  323. HMODULE hmod = LoadLibrary(szPath);
  324. if (hmod) {
  325. void (STDCALL *pDllRegisterServer)(void);
  326. (FARPROC&) pDllRegisterServer =
  327. GetProcAddress(hmod, txtDllRegisterServer);
  328. if (pDllRegisterServer)
  329. pDllRegisterServer();
  330. FreeLibrary(hmod);
  331. }
  332. // Register the full-text search module
  333. strcpy(pszEnd, txtItirclDll);
  334. hmod = LoadLibrary(szPath);
  335. if (hmod) {
  336. void (STDCALL *pDllRegisterServer)(void);
  337. (FARPROC&) pDllRegisterServer =
  338. GetProcAddress(hmod, txtDllRegisterServer);
  339. if (pDllRegisterServer)
  340. pDllRegisterServer();
  341. FreeLibrary(hmod);
  342. }
  343. // register our file extensions for Removable Media Support
  344. HKEY hKey;
  345. LPCTSTR szGUID = HHFINDER_GUID;
  346. LPCTSTR szExt = HHFINDER_EXTENSION;
  347. RegCreateKeyEx( HKEY_LOCAL_MACHINE, ITSS_FINDER, 0, NULL,
  348. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
  349. RegSetValueEx( hKey, szExt, 0, REG_SZ, (const unsigned char*) szGUID,
  350. (int)(strlen(szGUID) + 1) );
  351. RegCloseKey( hKey );
  352. _Module.RegisterServer(TRUE);
  353. return S_OK;
  354. }
  355. #endif
  356. void RegisterHH(PCSTR pszHHPath)
  357. {
  358. char szFullPath[MAX_PATH];
  359. SetRegKey(txtDefExtension, txtChmFile);
  360. LoadString(_Module.GetResourceInstance(),IDS_COMPILEDHTMLFILE,szFullPath,sizeof(szFullPath));
  361. SetRegKey(txtChmFile, szFullPath);
  362. // Put path in quotes, in case there are spaces in the folder name
  363. szFullPath[0] = '\042';
  364. strcpy(szFullPath + 1, pszHHPath);
  365. strcat(szFullPath, "\"");
  366. PSTR pszPathEnd = szFullPath + strlen(szFullPath);
  367. strcat(szFullPath, txtStdArg); // "pathname %1"
  368. char szBuf[MAX_PATH * 2];
  369. wsprintf(szBuf, txtShellOpenFmt, txtChmFile, txtCommand);
  370. SetRegKey(szBuf, szFullPath);
  371. // Register the icon to use for .chm files
  372. *pszPathEnd = '\0'; // remove the arguments
  373. strcpy(szFullPath + strlen(szFullPath) - 1, ",0"); // remove the close quote
  374. SetRegKey("chm.file\\DefaultIcon", szFullPath + 1);
  375. }
  376. static void SetRegKey(LPCTSTR pszKey, LPCTSTR pszValue)
  377. {
  378. RegSetValue(HKEY_CLASSES_ROOT, pszKey, REG_SZ, pszValue, (int)strlen(pszValue));
  379. }
  380. #ifndef HHUTIL
  381. //=--------------------------------------------------------------------------=
  382. // DllUnregisterServer
  383. //=--------------------------------------------------------------------------=
  384. // unregister's the Automation server
  385. STDAPI DllUnregisterServer(void)
  386. {
  387. HRESULT hr;
  388. hr = UnregisterAllObjects();
  389. RETURN_ON_FAILURE(hr);
  390. // call user unregistration function
  391. hr = UnregisterData();
  392. // Remove registration for decompression DLL (for .CHM files)
  393. HMODULE hmod = LoadLibrary(txtItssDll);
  394. if (hmod) {
  395. void (STDCALL *pDllRegisterServer)(void);
  396. (FARPROC&) pDllRegisterServer =
  397. GetProcAddress(hmod, txtDllUnRegisterServer);
  398. if (pDllRegisterServer)
  399. pDllRegisterServer();
  400. FreeLibrary(hmod);
  401. }
  402. // Remove registration for the full-text search module
  403. hmod = LoadLibrary(txtItirclDll);
  404. if (hmod) {
  405. void (STDCALL *pDllRegisterServer)(void);
  406. (FARPROC&) pDllRegisterServer =
  407. GetProcAddress(hmod, txtDllUnRegisterServer);
  408. if (pDllRegisterServer)
  409. pDllRegisterServer();
  410. FreeLibrary(hmod);
  411. }
  412. // unregister our file extensions for Removable Media Support
  413. HKEY hKey;
  414. LPCTSTR szGUID = HHFINDER_GUID;
  415. LPCTSTR szExt = HHFINDER_EXTENSION;
  416. RegCreateKeyEx( HKEY_LOCAL_MACHINE, ITSS_FINDER, 0, NULL,
  417. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
  418. RegDeleteKey( hKey, szExt );
  419. RegCloseKey( hKey );
  420. _Module.UnregisterServer();
  421. // BUGBUG: remove association with .CHM files
  422. return hr;
  423. }
  424. #endif
  425. #ifndef HHUTIL
  426. //=--------------------------------------------------------------------------=
  427. // DllCanUnloadNow
  428. //=--------------------------------------------------------------------------=
  429. // we are being asked whether or not it's okay to unload the DLL. just check
  430. // the lock counts on remaining objects ...
  431. //
  432. // Output:
  433. // HRESULT - S_OK, can unload now, S_FALSE, can't.
  434. STDAPI DllCanUnloadNow(void)
  435. {
  436. // if there are any objects lying around, then we can't unload. The
  437. // controlling CUnknownObject class that people should be inheriting from
  438. // takes care of this
  439. return (g_cLocks) ? S_FALSE : S_OK;
  440. }
  441. #endif
  442. #ifndef HHUTIL
  443. //=--------------------------------------------------------------------------=
  444. // DllGetClassObject
  445. //=--------------------------------------------------------------------------=
  446. // creates a ClassFactory object, and returns it.
  447. //
  448. // Parameters:
  449. // REFCLSID - CLSID for the class object
  450. // REFIID - interface we want class object to be.
  451. // void ** - pointer to where we should ptr to new object.
  452. //
  453. // Output:
  454. // HRESULT - S_OK, CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY,
  455. // E_INVALIDARG, E_UNEXPECTED
  456. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppvObjOut)
  457. {
  458. HRESULT hr;
  459. void *pv;
  460. int iIndex;
  461. if( IsEqualCLSID( rclsid, CLSID_HHSysSort ) || IsEqualCLSID( rclsid, CLSID_HHFinder ) )
  462. return _Module.GetClassObject( rclsid, riid, ppvObjOut );
  463. // arg checking
  464. if (!ppvObjOut)
  465. return E_INVALIDARG;
  466. // first of all, make sure they're asking for something we work with.
  467. iIndex = IndexOfOleObject(rclsid);
  468. if (iIndex == -1)
  469. return CLASS_E_CLASSNOTAVAILABLE;
  470. // create the blank object.
  471. pv = (void *)new CClassFactory(iIndex);
  472. if (!pv)
  473. return E_OUTOFMEMORY;
  474. // QI for whatever the user has asked for.
  475. //
  476. hr = ((IUnknown *)pv)->QueryInterface(riid, ppvObjOut);
  477. ((IUnknown *)pv)->Release();
  478. return hr;
  479. }
  480. #endif
  481. //=--------------------------------------------------------------------------=
  482. // IndexOfOleObject
  483. //=--------------------------------------------------------------------------=
  484. // returns the index in our global table of objects of the given CLSID. if
  485. // it's not a supported object, then we return -1
  486. //
  487. // Parameters:
  488. // REFCLSID - [in] duh.
  489. //
  490. // Output:
  491. // int - >= 0 is index into global table, -1 means not supported
  492. int IndexOfOleObject(REFCLSID rclsid)
  493. {
  494. int x = 0;
  495. // an object is creatable if it's CLSID is in the table of all allowable object
  496. // types.
  497. while (!ISEMPTYOBJECT(x)) {
  498. #ifdef _DEBUG
  499. CONTROLOBJECTINFO* pinfo = (CONTROLOBJECTINFO*) g_ObjectInfo[x].pInfo;
  500. #endif
  501. if (OBJECTISCREATABLE(x)) {
  502. if (rclsid == CLSIDOFOBJECT(x))
  503. return x;
  504. }
  505. x++;
  506. }
  507. return -1;
  508. }
  509. //=--------------------------------------------------------------------------=
  510. // RegisterAllObjects
  511. //=--------------------------------------------------------------------------=
  512. // registers all the objects for the given automation server.
  513. //
  514. // Parameters:
  515. // none
  516. //
  517. // Output:
  518. // HERSULT - S_OK, E_FAIL
  519. //
  520. // Notes:
  521. //
  522. const char g_szLibName[] = "Internet";
  523. HRESULT RegisterAllObjects(void)
  524. {
  525. HRESULT hr;
  526. int x = 0;
  527. // loop through all of our creatable objects [those that have a clsid in
  528. // our global table] and register them.
  529. while (!ISEMPTYOBJECT(x)) {
  530. #ifdef _DEBUG
  531. CONTROLOBJECTINFO* pinfo = (CONTROLOBJECTINFO*) g_ObjectInfo[x].pInfo;
  532. #endif
  533. if (!OBJECTISCREATABLE(x)) {
  534. x++;
  535. continue;
  536. }
  537. // depending on the object type, register different pieces of information
  538. switch (g_ObjectInfo[x].usType) {
  539. // for both simple co-creatable objects and proeprty pages, do the same
  540. // thing
  541. case OI_UNKNOWN:
  542. case OI_PROPERTYPAGE:
  543. RegisterUnknownObject(NAMEOFOBJECT(x), CLSIDOFOBJECT(x));
  544. break;
  545. case OI_AUTOMATION:
  546. RegisterAutomationObject(g_szLibName, NAMEOFOBJECT(x),
  547. VERSIONOFOBJECT(x), *g_pLibid, CLSIDOFOBJECT(x));
  548. break;
  549. case OI_CONTROL:
  550. RegisterControlObject(g_szLibName, NAMEOFOBJECT(x),
  551. VERSIONOFOBJECT(x), *g_pLibid, CLSIDOFOBJECT(x),
  552. OLEMISCFLAGSOFCONTROL(x), BITMAPIDOFCONTROL(x));
  553. break;
  554. }
  555. x++;
  556. }
  557. // Load and register our type library.
  558. if (g_fServerHasTypeLibrary) {
  559. char szTmp[MAX_PATH];
  560. DWORD dwPathLen = GetModuleFileName(_Module.GetModuleInstance(), szTmp, MAX_PATH);
  561. MAKE_WIDEPTR_FROMANSI(pwsz, szTmp);
  562. ITypeLib *pTypeLib;
  563. hr = LoadTypeLib(pwsz, &pTypeLib);
  564. RETURN_ON_FAILURE(hr);
  565. hr = RegisterTypeLib(pTypeLib, pwsz, NULL);
  566. pTypeLib->Release();
  567. RETURN_ON_FAILURE(hr);
  568. }
  569. return S_OK;
  570. }
  571. //=--------------------------------------------------------------------------=
  572. // UnregisterAllObjects
  573. //=--------------------------------------------------------------------------=
  574. // un-registers all the objects for the given automation server.
  575. //
  576. // Parameters:
  577. // none
  578. //
  579. // Output:
  580. // HRESULT - S_OK
  581. HRESULT UnregisterAllObjects(void)
  582. {
  583. int x = 0;
  584. // loop through all of our creatable objects [those that have a clsid in
  585. // our global table] and register them.
  586. //
  587. while (!ISEMPTYOBJECT(x)) {
  588. #ifdef _DEBUG
  589. CONTROLOBJECTINFO* pinfo = (CONTROLOBJECTINFO*) g_ObjectInfo[x].pInfo;
  590. #endif
  591. if (!OBJECTISCREATABLE(x)) {
  592. x++;
  593. continue;
  594. }
  595. switch (g_ObjectInfo[x].usType) {
  596. case OI_UNKNOWN:
  597. case OI_PROPERTYPAGE:
  598. UnregisterUnknownObject(CLSIDOFOBJECT(x));
  599. break;
  600. case OI_CONTROL:
  601. UnregisterControlObject(g_szLibName, NAMEOFOBJECT(x),
  602. VERSIONOFOBJECT(x), CLSIDOFOBJECT(x));
  603. case OI_AUTOMATION:
  604. UnregisterAutomationObject(g_szLibName, NAMEOFOBJECT(x),
  605. VERSIONOFOBJECT(x), CLSIDOFOBJECT(x));
  606. break;
  607. }
  608. x++;
  609. }
  610. /*
  611. * if we've got one, unregister our type library [this isn't an API
  612. * function -- we've implemented this ourselves]
  613. */
  614. if (g_pLibid)
  615. UnregisterTypeLibrary(*g_pLibid);
  616. return S_OK;
  617. }
  618. //=--------------------------------------------------------------------------=
  619. // UnregisterData
  620. //=--------------------------------------------------------------------------=
  621. // inproc server writers should unregister anything they registered in
  622. // RegisterData() here.
  623. //
  624. // Output:
  625. // BOOL - false means failure.
  626. BOOL UnregisterData(void)
  627. {
  628. HRESULT hr;
  629. hr = UnRegisterCLSIDInCategory(CLSID_HHCtrl, CATID_SafeForScripting);
  630. hr = UnRegisterCLSIDInCategory(CLSID_HHCtrl, CATID_SafeForInitializing);
  631. return TRUE;
  632. }