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.

457 lines
11 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. winssnap.cpp
  7. WINS snapin entry points/registration functions
  8. Note: Proxy/Stub Information
  9. To build a separate proxy/stub DLL,
  10. run nmake -f Snapinps.mak in the project directory.
  11. FILE HISTORY:
  12. */
  13. #include "stdafx.h"
  14. #include "initguid.h"
  15. #include "winscomp.h"
  16. #include "winssnap.h"
  17. #include "ncglobal.h" // network console global defines
  18. #include "cmptrmgr.h" // computer management snapin node types
  19. #include "locale.h" // for setlocale
  20. #include <lmerr.h> // for NERR stuff
  21. #ifdef _DEBUG
  22. void DbgVerifyInstanceCounts();
  23. #define DEBUG_VERIFY_INSTANCE_COUNTS DbgVerifyInstanceCounts()
  24. #else
  25. #define DEBUG_VERIFY_INSTANCE_COUNTS
  26. #endif
  27. CComModule _Module;
  28. BEGIN_OBJECT_MAP(ObjectMap)
  29. OBJECT_ENTRY(CLSID_WinsSnapin, CWinsComponentDataPrimary)
  30. OBJECT_ENTRY(CLSID_WinsSnapinExtension, CWinsComponentDataExtension)
  31. OBJECT_ENTRY(CLSID_WinsSnapinAbout, CWinsAbout)
  32. END_OBJECT_MAP()
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. CWinsSnapinApp theApp;
  39. BOOL CWinsSnapinApp::InitInstance()
  40. {
  41. _Module.Init(ObjectMap, m_hInstance);
  42. //
  43. // Initialize the CWndIpAddress control window class IPADDRESS
  44. //
  45. CWndIpAddress::CreateWindowClass( m_hInstance ) ;
  46. // set the default locale to the system locale
  47. setlocale(LC_ALL, "");
  48. //
  49. // Initialize use of the WinSock routines
  50. //
  51. WSADATA wsaData ;
  52. if ( ::WSAStartup( MAKEWORD( 1, 1 ), & wsaData ) != 0 )
  53. {
  54. m_bWinsockInited = TRUE;
  55. Trace0("InitInstance: Winsock initialized!\n");
  56. }
  57. else
  58. {
  59. m_bWinsockInited = FALSE;
  60. }
  61. ::IPAddrInit(m_hInstance);
  62. return CWinApp::InitInstance();
  63. }
  64. int CWinsSnapinApp::ExitInstance()
  65. {
  66. _Module.Term();
  67. DEBUG_VERIFY_INSTANCE_COUNTS;
  68. //
  69. // Terminate use of the WinSock routines.
  70. //
  71. if ( m_bWinsockInited )
  72. {
  73. WSACleanup() ;
  74. }
  75. return CWinApp::ExitInstance();
  76. }
  77. /***
  78. *
  79. * CWinsadmnApp::GetSystemMessage
  80. *
  81. * Purpose:
  82. *
  83. * Given a message ID, determine where the message resides,
  84. * and load it into the buffer.
  85. *
  86. * Arguments:
  87. *
  88. * UINT nId Message ID number
  89. * char * chBuffer Character buffer to load into.
  90. * int cbBuffSize Size of buffer in characters
  91. *
  92. * Returns:
  93. *
  94. * API error return code, or ERROR_SUCCESS
  95. *
  96. */
  97. DWORD
  98. CWinsSnapinApp::GetSystemMessage(
  99. UINT nId,
  100. TCHAR * chBuffer,
  101. int cbBuffSize
  102. )
  103. {
  104. TCHAR * pszText = NULL ;
  105. HINSTANCE hdll = NULL ;
  106. DWORD flags = FORMAT_MESSAGE_IGNORE_INSERTS
  107. | FORMAT_MESSAGE_MAX_WIDTH_MASK;
  108. //
  109. // Interpret the error. Need to special case
  110. // the lmerr & ntstatus ranges.
  111. //
  112. if( nId >= NERR_BASE && nId <= MAX_NERR )
  113. {
  114. hdll = ::LoadLibrary( _T("netmsg.dll") );
  115. }
  116. else if( nId >= 0x40000000L )
  117. {
  118. hdll = ::LoadLibrary( _T("ntdll.dll") );
  119. }
  120. if( hdll == NULL )
  121. {
  122. flags |= FORMAT_MESSAGE_FROM_SYSTEM;
  123. }
  124. else
  125. {
  126. flags |= FORMAT_MESSAGE_FROM_HMODULE;
  127. }
  128. DWORD dwResult = ::FormatMessage( flags,
  129. (LPVOID) hdll,
  130. nId,
  131. 0,
  132. chBuffer,
  133. cbBuffSize,
  134. NULL );
  135. if( hdll != NULL )
  136. {
  137. LONG err = ::GetLastError();
  138. ::FreeLibrary( hdll );
  139. if ( dwResult == 0 )
  140. {
  141. ::SetLastError( err );
  142. }
  143. }
  144. return dwResult ? ERROR_SUCCESS : ::GetLastError();
  145. }
  146. /***
  147. *
  148. * CWinsadmnApp::MessageBox
  149. *
  150. * Purpose:
  151. *
  152. * Replacement for AfxMessageBox(). This function will call up the
  153. * appropriate message from wherever before displaying it
  154. *
  155. * Arguments:
  156. *
  157. * UINT nIdPrompt Message ID
  158. * UINT nType AfxMessageBox type (YESNO, OKCANCEL, etc)
  159. * UINT nHelpContext Help context ID for AfxMessageBox();
  160. *
  161. * Notes:
  162. *
  163. * If an error occurs, a standard message (hard-coded in english) will
  164. * be shown that gives the error number.
  165. *
  166. */
  167. int
  168. CWinsSnapinApp::MessageBox (
  169. UINT nIdPrompt,
  170. UINT nType,
  171. UINT nHelpContext
  172. )
  173. {
  174. //
  175. // Substitute a friendly message for "RPC server not
  176. // available" and "No more endpoints available from
  177. // the endpoint mapper".
  178. //
  179. if (nIdPrompt == EPT_S_NOT_REGISTERED ||
  180. nIdPrompt == RPC_S_SERVER_UNAVAILABLE)
  181. {
  182. nIdPrompt = IDS_ERR_WINS_DOWN;
  183. }
  184. //
  185. // If it's our error, the text is in our resource segment.
  186. // Otherwise, use FormatMessage() and the appropriate DLL>
  187. //
  188. if ((nIdPrompt >= IDS_ERR_INVALID_IP) && (nIdPrompt <= IDS_MSG_LAST))
  189. {
  190. return ::AfxMessageBox(nIdPrompt, nType, nHelpContext);
  191. }
  192. TCHAR szMesg [1024] ;
  193. int nResult;
  194. if ((nResult = GetSystemMessage(nIdPrompt, szMesg, sizeof(szMesg)/sizeof(TCHAR)))
  195. == ERROR_SUCCESS)
  196. {
  197. return ::AfxMessageBox(szMesg, nType, nHelpContext);
  198. }
  199. Trace1("Message number %d not found", nIdPrompt);
  200. ASSERT(0 && "Error Message ID not handled");
  201. //
  202. // Do something for the retail version
  203. //
  204. ::wsprintf ( szMesg, _T("Error: %lu"), nIdPrompt);
  205. ::AfxMessageBox(szMesg, nType, nHelpContext);
  206. return nResult;
  207. }
  208. int
  209. CWinsSnapinApp::MessageBox (
  210. LPCTSTR pPrefixText,
  211. UINT nIdPrompt,
  212. UINT nType,
  213. UINT nHelpContext
  214. )
  215. {
  216. CString strText = pPrefixText;
  217. CString strAppend;
  218. //
  219. // Substitute a friendly message for "RPC server not
  220. // available" and "No more endpoints available from
  221. // the endpoint mapper".
  222. //
  223. if (nIdPrompt == EPT_S_NOT_REGISTERED ||
  224. nIdPrompt == RPC_S_SERVER_UNAVAILABLE)
  225. {
  226. nIdPrompt = IDS_ERR_WINS_DOWN;
  227. }
  228. //
  229. // If it's our error, the text is in our resource segment.
  230. // Otherwise, use FormatMessage() and the appropriate DLL>
  231. //
  232. if ((nIdPrompt >= IDS_ERR_BASE) && (nIdPrompt <= IDS_MSG_LAST))
  233. {
  234. strAppend.LoadString(nIdPrompt);
  235. strText += strAppend;
  236. return ::AfxMessageBox(strText, nType, nHelpContext);
  237. }
  238. TCHAR szMesg [1024] ;
  239. int nResult;
  240. if ((nResult = GetSystemMessage(nIdPrompt, szMesg, sizeof(szMesg)/sizeof(TCHAR)))
  241. == ERROR_SUCCESS)
  242. {
  243. strText += szMesg;
  244. return ::AfxMessageBox(strText, nType, nHelpContext);
  245. }
  246. Trace1("Message number %d not found", nIdPrompt);
  247. ASSERT(0 && "Error Message ID not handled");
  248. //
  249. // Do something for the retail version
  250. //
  251. ::wsprintf ( szMesg, _T("Error: %lu"), nIdPrompt);
  252. strText += szMesg;
  253. ::AfxMessageBox(strText, nType, nHelpContext);
  254. return nResult;
  255. }
  256. /////////////////////////////////////////////////////////////////////////////
  257. // Used to determine whether the DLL can be unloaded by OLE
  258. STDAPI DllCanUnloadNow(void)
  259. {
  260. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  261. return (AfxDllCanUnloadNow()==S_OK && _Module.GetLockCount()==0) ? S_OK : S_FALSE;
  262. }
  263. /////////////////////////////////////////////////////////////////////////////
  264. // Returns a class factory to create an object of the requested type
  265. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  266. {
  267. return _Module.GetClassObject(rclsid, riid, ppv);
  268. }
  269. /////////////////////////////////////////////////////////////////////////////
  270. // DllRegisterServer - Adds entries to the system registry
  271. STDAPI DllRegisterServer(void)
  272. {
  273. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  274. //
  275. // registers object, typelib and all interfaces in typelib
  276. //
  277. HRESULT hr = _Module.RegisterServer(/* bRegTypeLib */ FALSE);
  278. ASSERT(SUCCEEDED(hr));
  279. if (FAILED(hr))
  280. return hr;
  281. CString strDesc, strExtDesc, strRootDesc, strVersion;
  282. strDesc.LoadString(IDS_SNAPIN_DESC);
  283. strExtDesc.LoadString(IDS_SNAPIN_EXTENSION_DESC);
  284. strRootDesc.LoadString(IDS_ROOT_DESC);
  285. strVersion.LoadString(IDS_ABOUT_VERSION);
  286. //
  287. // register the snapin into the console snapin list
  288. //
  289. hr = RegisterSnapinGUID(&CLSID_WinsSnapin,
  290. &GUID_WinsRootNodeType,
  291. &CLSID_WinsSnapinAbout,
  292. strDesc,
  293. strVersion,
  294. TRUE);
  295. ASSERT(SUCCEEDED(hr));
  296. if (FAILED(hr))
  297. return hr;
  298. hr = RegisterSnapinGUID(&CLSID_WinsSnapinExtension,
  299. NULL,
  300. &CLSID_WinsSnapinAbout,
  301. strExtDesc,
  302. strVersion,
  303. FALSE);
  304. ASSERT(SUCCEEDED(hr));
  305. if (FAILED(hr))
  306. return hr;
  307. //
  308. // register the snapin nodes into the console node list
  309. //
  310. hr = RegisterNodeTypeGUID(&CLSID_WinsSnapin,
  311. &GUID_WinsRootNodeType,
  312. strRootDesc);
  313. ASSERT(SUCCEEDED(hr));
  314. #ifdef __NETWORK_CONSOLE__
  315. hr = RegisterAsRequiredExtensionGUID(&GUID_NetConsRootNodeType,
  316. &CLSID_WinsSnapinExtension,
  317. strExtDesc,
  318. EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
  319. &CLSID_WinsSnapinExtension); // the value doesn't matter,
  320. // just needs to be non-null
  321. ASSERT(SUCCEEDED(hr));
  322. #endif
  323. hr = RegisterAsRequiredExtensionGUID(&NODETYPE_COMPUTERMANAGEMENT_SERVERAPPS,
  324. &CLSID_WinsSnapinExtension,
  325. strExtDesc,
  326. EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
  327. &NODETYPE_COMPUTERMANAGEMENT_SERVERAPPS); // NULL : not dynamic
  328. ASSERT(SUCCEEDED(hr));
  329. return hr;
  330. }
  331. /////////////////////////////////////////////////////////////////////////////
  332. // DllUnregisterServer - Removes entries from the system registry
  333. STDAPI DllUnregisterServer(void)
  334. {
  335. HRESULT hr = _Module.UnregisterServer();
  336. ASSERT(SUCCEEDED(hr));
  337. if (FAILED(hr))
  338. return hr;
  339. // un register the snapin
  340. //
  341. hr = UnregisterSnapinGUID(&CLSID_WinsSnapin);
  342. ASSERT(SUCCEEDED(hr));
  343. if (FAILED(hr))
  344. return hr;
  345. hr = UnregisterSnapinGUID(&CLSID_WinsSnapinExtension);
  346. if (FAILED(hr))
  347. return hr;
  348. // unregister the snapin nodes
  349. //
  350. hr = UnregisterNodeTypeGUID(&GUID_WinsRootNodeType);
  351. ASSERT(SUCCEEDED(hr));
  352. if (FAILED(hr))
  353. return hr;
  354. #ifdef __NETWORK_CONSOLE__
  355. hr = UnregisterAsRequiredExtensionGUID(&GUID_NetConsRootNodeType,
  356. &CLSID_WinsSnapinExtension,
  357. EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
  358. &CLSID_WinsSnapinExtension);
  359. ASSERT(SUCCEEDED(hr));
  360. #endif
  361. // computer management snapin extension
  362. hr = UnregisterAsRequiredExtensionGUID(&NODETYPE_COMPUTERMANAGEMENT_SERVERAPPS,
  363. &CLSID_WinsSnapinExtension,
  364. EXTENSION_TYPE_TASK | EXTENSION_TYPE_NAMESPACE,
  365. &CLSID_WinsSnapinExtension);
  366. ASSERT(SUCCEEDED(hr));
  367. if (FAILED(hr))
  368. return hr;
  369. return hr;
  370. }
  371. #ifdef _DEBUG
  372. void DbgVerifyInstanceCounts()
  373. {
  374. DEBUG_VERIFY_INSTANCE_COUNT(CHandler);
  375. DEBUG_VERIFY_INSTANCE_COUNT(CMTHandler);
  376. }
  377. #endif // _DEBUG