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.

866 lines
16 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. appobj.cpp
  5. Abstract:
  6. OLE-createable application object implementation.
  7. Author:
  8. Don Ryan (donryan) 27-Dec-1994
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 16-Jan-1996
  13. Added Get/SetLastTargetServer() to help isolate server connection
  14. problems. (Bug #2993.)
  15. --*/
  16. #include "stdafx.h"
  17. #include "llsmgr.h"
  18. #include "lmerr.h"
  19. #include "lmcons.h"
  20. #include "lmwksta.h"
  21. #include "lmapibuf.h"
  22. #include "lmserver.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char BASED_CODE THIS_FILE[] = __FILE__;
  26. #endif
  27. IMPLEMENT_DYNCREATE(CApplication, CCmdTarget)
  28. // IMPLEMENT_OLECREATE(CApplication, "Llsmgr.Application.1", 0x2c5dffb3, 0x472f, 0x11ce, 0xa0, 0x30, 0x0, 0xaa, 0x0, 0x33, 0x9a, 0x98)
  29. BEGIN_MESSAGE_MAP(CApplication, CCmdTarget)
  30. //{{AFX_MSG_MAP(CApplication)
  31. // NOTE - the ClassWizard will add and remove mapping macros here.
  32. //}}AFX_MSG_MAP
  33. END_MESSAGE_MAP()
  34. BEGIN_DISPATCH_MAP(CApplication, CCmdTarget)
  35. //{{AFX_DISPATCH_MAP(CApplication)
  36. DISP_PROPERTY_EX(CApplication, "Application", GetApplication, SetNotSupported, VT_DISPATCH)
  37. DISP_PROPERTY_EX(CApplication, "FullName", GetFullName, SetNotSupported, VT_BSTR)
  38. DISP_PROPERTY_EX(CApplication, "Name", GetName, SetNotSupported, VT_BSTR)
  39. DISP_PROPERTY_EX(CApplication, "Parent", GetParent, SetNotSupported, VT_DISPATCH)
  40. DISP_PROPERTY_EX(CApplication, "Visible", GetVisible, SetNotSupported, VT_BOOL)
  41. DISP_PROPERTY_EX(CApplication, "ActiveController", GetActiveController, SetNotSupported, VT_DISPATCH)
  42. DISP_PROPERTY_EX(CApplication, "ActiveDomain", GetActiveDomain, SetNotSupported, VT_DISPATCH)
  43. DISP_PROPERTY_EX(CApplication, "LocalDomain", GetLocalDomain, SetNotSupported, VT_DISPATCH)
  44. DISP_PROPERTY_EX(CApplication, "IsFocusDomain", IsFocusDomain, SetNotSupported, VT_BOOL)
  45. DISP_PROPERTY_EX(CApplication, "LastErrorString", GetLastErrorString, SetNotSupported, VT_BSTR)
  46. DISP_FUNCTION(CApplication, "Quit", Quit, VT_EMPTY, VTS_NONE)
  47. DISP_FUNCTION(CApplication, "SelectDomain", SelectDomain, VT_BOOL, VTS_VARIANT)
  48. DISP_FUNCTION(CApplication, "SelectEnterprise", SelectEnterprise, VT_BOOL, VTS_NONE)
  49. DISP_PROPERTY_PARAM(CApplication, "Domains", GetDomains, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  50. DISP_DEFVALUE(CApplication, "Name")
  51. //}}AFX_DISPATCH_MAP
  52. END_DISPATCH_MAP()
  53. CApplication::CApplication()
  54. /*++
  55. Routine Description:
  56. Constructor for OLE-createable application object.
  57. To keep the application running as long as an OLE automation
  58. object is active, we must call AfxOleLockApp.
  59. Arguments:
  60. None.
  61. Return Values:
  62. None.
  63. --*/
  64. {
  65. EnableAutomation();
  66. ASSERT(theApp.m_pApplication == NULL);
  67. if (theApp.m_pApplication == NULL)
  68. theApp.m_pApplication = this;
  69. if (theApp.m_bIsAutomated)
  70. AfxOleLockApp();
  71. m_pDomains = NULL;
  72. m_pLocalDomain = NULL;
  73. m_pActiveDomain = NULL;
  74. m_bIsFocusDomain = FALSE;
  75. m_bDomainsRefreshed = FALSE;
  76. m_strLastTargetServer = TEXT("");
  77. m_domainArray.RemoveAll();
  78. m_pActiveController = new CController;
  79. m_idStatus = m_pActiveController ? STATUS_SUCCESS : STATUS_NO_MEMORY;
  80. }
  81. CApplication::~CApplication()
  82. /*++
  83. Routine Description:
  84. Destructor for OLE-createable application object.
  85. Arguments:
  86. None.
  87. Return Values:
  88. None.
  89. --*/
  90. {
  91. ASSERT(theApp.m_pApplication == this);
  92. if (theApp.m_pApplication == this)
  93. theApp.m_pApplication = NULL;
  94. if (theApp.m_bIsAutomated)
  95. AfxOleUnlockApp();
  96. if (m_pDomains)
  97. m_pDomains->InternalRelease();
  98. if (m_pLocalDomain)
  99. m_pLocalDomain->InternalRelease();
  100. if (m_pActiveDomain)
  101. m_pActiveDomain->InternalRelease();
  102. if (m_pActiveController)
  103. m_pActiveController->InternalRelease();
  104. }
  105. void CApplication::OnFinalRelease()
  106. /*++
  107. Routine Description:
  108. When the last reference for an automation object is released
  109. OnFinalRelease is called. This implementation deletes object.
  110. Arguments:
  111. None.
  112. Return Values:
  113. None.
  114. --*/
  115. {
  116. ResetDomains();
  117. delete this;
  118. }
  119. LPDISPATCH CApplication::GetActiveController()
  120. /*++
  121. Routine Description:
  122. Returns the active license controller object.
  123. Arguments:
  124. None.
  125. Return Values:
  126. VT_DISPATCH or VT_EMPTY.
  127. --*/
  128. {
  129. ASSERT_VALID(m_pActiveController);
  130. return m_pActiveController->GetIDispatch(TRUE);
  131. }
  132. LPDISPATCH CApplication::GetActiveDomain()
  133. /*++
  134. Routine Description:
  135. Returns the active domain object.
  136. Arguments:
  137. None.
  138. Return Values:
  139. VT_DISPATCH or VT_EMPTY.
  140. --*/
  141. {
  142. return m_pActiveDomain ? m_pActiveDomain->GetIDispatch(TRUE) : NULL;
  143. }
  144. LPDISPATCH CApplication::GetApplication()
  145. /*++
  146. Routine Description:
  147. Returns the application object.
  148. Arguments:
  149. None.
  150. Return Values:
  151. VT_DISPATCH.
  152. --*/
  153. {
  154. return GetIDispatch(TRUE);
  155. }
  156. LPDISPATCH CApplication::GetDomains(const VARIANT FAR& index)
  157. /*++
  158. Routine Description:
  159. Returns a collection object containing all of the domains
  160. visible to the local machine or returns an individual domain
  161. described by an index into the collection.
  162. Arguments:
  163. index - optional argument that may be a string (VT_BSTR)
  164. indicating a domain name or a number (VT_I4) indicating
  165. the position within collection.
  166. Return Values:
  167. VT_DISPATCH or VT_EMPTY.
  168. --*/
  169. {
  170. LPDISPATCH lpdispatch = NULL;
  171. if (!m_pDomains)
  172. {
  173. m_pDomains = new CDomains(this, &m_domainArray);
  174. }
  175. if (m_pDomains)
  176. {
  177. if (V_ISVOID((VARIANT FAR*)&index))
  178. {
  179. if (RefreshDomains())
  180. {
  181. lpdispatch = m_pDomains->GetIDispatch(TRUE);
  182. }
  183. }
  184. else
  185. {
  186. if (m_bDomainsRefreshed)
  187. {
  188. lpdispatch = m_pDomains->GetItem(index);
  189. }
  190. else if (RefreshDomains())
  191. {
  192. lpdispatch = m_pDomains->GetItem(index);
  193. }
  194. }
  195. }
  196. else
  197. {
  198. SetLastStatus(STATUS_NO_MEMORY);
  199. }
  200. return lpdispatch;
  201. }
  202. BSTR CApplication::GetFullName()
  203. /*++
  204. Routine Description:
  205. Returns the file specification for the application,
  206. including path.
  207. Arguments:
  208. None.
  209. Return Values:
  210. VT_BSTR.
  211. --*/
  212. {
  213. TCHAR szModuleFileName[MAX_PATH+1] = {0};
  214. DWORD cch;
  215. BSTR bstrFullName = NULL;
  216. cch = GetModuleFileName(AfxGetApp()->m_hInstance, szModuleFileName, MAX_PATH);
  217. if (0 != cch && MAX_PATH != cch)
  218. {
  219. bstrFullName = SysAllocStringLen(szModuleFileName, lstrlen(szModuleFileName));
  220. }
  221. return bstrFullName;
  222. }
  223. BSTR CApplication::GetLastErrorString()
  224. /*++
  225. Routine Description:
  226. Retrieves string for last error.
  227. (Routine stolen from winsadmn...).
  228. Arguments:
  229. None.
  230. Return Values:
  231. VT_BSTR.
  232. --*/
  233. {
  234. CString strLastError;
  235. DWORD nId = m_idStatus;
  236. if (((long)nId == RPC_S_CALL_FAILED) ||
  237. ((long)nId == RPC_NT_SS_CONTEXT_MISMATCH))
  238. {
  239. strLastError.LoadString(IDP_ERROR_DROPPED_LINK);
  240. }
  241. else if (((long)nId == RPC_S_SERVER_UNAVAILABLE) ||
  242. ((long)nId == RPC_NT_SERVER_UNAVAILABLE))
  243. {
  244. strLastError.LoadString(IDP_ERROR_NO_RPC_SERVER);
  245. }
  246. else if ((long)nId == STATUS_MEMBER_IN_GROUP)
  247. {
  248. strLastError.LoadString(IDP_ERROR_MEMBER_IN_GROUP);
  249. }
  250. else
  251. {
  252. HINSTANCE hinstDll = NULL;
  253. if ((nId >= NERR_BASE) && (nId <= MAX_NERR))
  254. {
  255. hinstDll = ::LoadLibrary(_T("netmsg.dll"));
  256. }
  257. else if (nId >= 0x4000000)
  258. {
  259. hinstDll = ::LoadLibrary(_T("ntdll.dll"));
  260. }
  261. TCHAR szLastError[1024];
  262. DWORD cchLastError = sizeof(szLastError) / sizeof(TCHAR);
  263. DWORD dwFlags = FORMAT_MESSAGE_IGNORE_INSERTS|
  264. FORMAT_MESSAGE_MAX_WIDTH_MASK|
  265. (hinstDll ? FORMAT_MESSAGE_FROM_HMODULE
  266. : FORMAT_MESSAGE_FROM_SYSTEM);
  267. cchLastError = ::FormatMessage(
  268. dwFlags,
  269. hinstDll,
  270. nId,
  271. 0,
  272. szLastError,
  273. cchLastError,
  274. NULL
  275. );
  276. if (hinstDll)
  277. {
  278. ::FreeLibrary(hinstDll);
  279. }
  280. if (cchLastError)
  281. {
  282. strLastError = szLastError;
  283. }
  284. else
  285. {
  286. strLastError.LoadString(IDP_ERROR_UNSUCCESSFUL);
  287. }
  288. }
  289. return strLastError.AllocSysString();
  290. }
  291. LPDISPATCH CApplication::GetLocalDomain()
  292. /*++
  293. Routine Description:
  294. Returns the local domain object.
  295. Arguments:
  296. None.
  297. Return Values:
  298. VT_DISPATCH or VT_EMPTY.
  299. --*/
  300. {
  301. if (!m_pLocalDomain)
  302. {
  303. NET_API_STATUS NetStatus;
  304. PWKSTA_INFO_100 pWkstaInfo100 = NULL;
  305. NetStatus = NetWkstaGetInfo(
  306. NULL,
  307. 100,
  308. (LPBYTE*)&pWkstaInfo100
  309. );
  310. if (NetStatus == ERROR_SUCCESS)
  311. {
  312. m_pLocalDomain = new CDomain(this, pWkstaInfo100->wki100_langroup);
  313. if (!m_pLocalDomain)
  314. {
  315. NetStatus = ERROR_NOT_ENOUGH_MEMORY;
  316. }
  317. NetApiBufferFree(pWkstaInfo100);
  318. }
  319. SetLastStatus(NetStatus); // called api
  320. }
  321. return m_pLocalDomain ? m_pLocalDomain->GetIDispatch(TRUE) : NULL;
  322. }
  323. BSTR CApplication::GetName()
  324. /*++
  325. Routine Description:
  326. Returns the name of the application.
  327. Arguments:
  328. None.
  329. Return Values:
  330. VT_BSTR.
  331. --*/
  332. {
  333. CString AppName = AfxGetAppName();
  334. return AppName.AllocSysString();
  335. }
  336. LPDISPATCH CApplication::GetParent()
  337. /*++
  338. Routine Description:
  339. Returns the parent of the object.
  340. Arguments:
  341. None.
  342. Return Values:
  343. VT_DISPATCH.
  344. --*/
  345. {
  346. return GetApplication();
  347. }
  348. BOOL CApplication::GetVisible()
  349. /*++
  350. Routine Description:
  351. Returns whether or not the application is visible to the user.
  352. Arguments:
  353. None.
  354. Return Values:
  355. VT_BOOL.
  356. --*/
  357. {
  358. return FALSE;
  359. }
  360. BOOL CApplication::IsFocusDomain()
  361. /*++
  362. Routine Description:
  363. Returns true if application focused on domain.
  364. Arguments:
  365. None.
  366. Return Values:
  367. VT_BOOL.
  368. --*/
  369. {
  370. return m_bIsFocusDomain;
  371. }
  372. BOOL CApplication::RefreshDomains()
  373. /*++
  374. Routine Description:
  375. Refreshs domain object list.
  376. Arguments:
  377. None.
  378. Return Values:
  379. None.
  380. --*/
  381. {
  382. ResetDomains();
  383. NET_API_STATUS NetStatus;
  384. DWORD ResumeHandle = 0L;
  385. int iDomain = 0;
  386. do
  387. {
  388. DWORD EntriesRead;
  389. DWORD TotalEntries;
  390. LPBYTE ReturnBuffer = NULL;
  391. NetStatus = NetServerEnum(
  392. NULL, // servername
  393. 100, // level
  394. &ReturnBuffer,
  395. LLS_PREFERRED_LENGTH,
  396. &EntriesRead,
  397. &TotalEntries,
  398. SV_TYPE_DOMAIN_ENUM,
  399. NULL, // domain
  400. &ResumeHandle
  401. );
  402. if (NetStatus == ERROR_SUCCESS ||
  403. NetStatus == ERROR_MORE_DATA)
  404. {
  405. CDomain* pDomain;
  406. PSERVER_INFO_100 pServerInfo100;
  407. pServerInfo100 = (PSERVER_INFO_100)ReturnBuffer;
  408. ASSERT(iDomain == m_domainArray.GetSize());
  409. m_domainArray.SetSize(m_domainArray.GetSize() + EntriesRead);
  410. while (EntriesRead--)
  411. {
  412. pDomain = new CDomain(this, pServerInfo100->sv100_name);
  413. m_domainArray.SetAt(iDomain++, pDomain); // validate later
  414. pServerInfo100++;
  415. }
  416. NetApiBufferFree(ReturnBuffer);
  417. }
  418. } while (NetStatus == ERROR_MORE_DATA);
  419. SetLastStatus(NetStatus); // called api
  420. if (NetStatus == ERROR_SUCCESS)
  421. {
  422. m_bDomainsRefreshed = TRUE;
  423. }
  424. else
  425. {
  426. ResetDomains();
  427. }
  428. return m_bDomainsRefreshed;
  429. }
  430. void CApplication::ResetDomains()
  431. /*++
  432. Routine Description:
  433. Resets domain object list.
  434. Arguments:
  435. None.
  436. Return Values:
  437. None.
  438. --*/
  439. {
  440. CDomain* pDomain;
  441. INT_PTR iDomain = m_domainArray.GetSize();
  442. while (iDomain--)
  443. {
  444. pDomain = (CDomain*)m_domainArray[iDomain];
  445. if (NULL != pDomain)
  446. {
  447. ASSERT(pDomain->IsKindOf(RUNTIME_CLASS(CDomain)));
  448. pDomain->InternalRelease();
  449. }
  450. }
  451. m_domainArray.RemoveAll();
  452. m_bDomainsRefreshed = FALSE;
  453. }
  454. BOOL CApplication::SelectDomain(const VARIANT FAR& domain)
  455. /*++
  456. Routine Description:
  457. Connects to license controller of specified domain.
  458. Arguments:
  459. domain - name of domain.
  460. Return Values:
  461. VT_BOOL.
  462. --*/
  463. {
  464. BOOL bIsSelected = FALSE;
  465. ASSERT_VALID(m_pActiveController);
  466. bIsSelected = m_pActiveController->Connect(domain);
  467. if (FALSE != bIsSelected)
  468. {
  469. LPTSTR pszActiveDomain = MKSTR(m_pActiveController->m_strActiveDomainName);
  470. if (m_pActiveDomain)
  471. {
  472. m_pActiveDomain->InternalRelease();
  473. m_pActiveDomain = NULL;
  474. }
  475. if (pszActiveDomain && *pszActiveDomain)
  476. {
  477. m_pActiveDomain = new CDomain(this, pszActiveDomain);
  478. if (m_pActiveDomain)
  479. {
  480. m_bIsFocusDomain = TRUE;
  481. }
  482. else
  483. {
  484. m_bIsFocusDomain = FALSE; // invalidate m_pActiveDomain
  485. SetLastStatus(STATUS_NO_MEMORY);
  486. }
  487. }
  488. else
  489. {
  490. m_bIsFocusDomain = FALSE; // invalidate m_pActiveDomain
  491. }
  492. }
  493. return bIsSelected;
  494. }
  495. BOOL CApplication::SelectEnterprise()
  496. /*++
  497. Routine Description:
  498. Connects to license controller of enterprise.
  499. Arguments:
  500. None.
  501. Return Values:
  502. VT_BOOL.
  503. --*/
  504. {
  505. BOOL bIsSelected = FALSE;
  506. VARIANT va;
  507. VariantInit(&va); // connect to default controller
  508. bIsSelected = m_pActiveController->Connect(va);
  509. if (FALSE != bIsSelected)
  510. {
  511. if (m_pActiveDomain)
  512. {
  513. m_pActiveDomain->InternalRelease();
  514. m_pActiveDomain = NULL;
  515. }
  516. m_bIsFocusDomain = FALSE;
  517. }
  518. return bIsSelected;
  519. }
  520. void CApplication::Quit()
  521. /*++
  522. Routine Description:
  523. Closes all documents and exits the application.
  524. Arguments:
  525. None.
  526. Return Values:
  527. None.
  528. --*/
  529. {
  530. AfxPostQuitMessage(0); // no main window...
  531. }
  532. BSTR CApplication::GetLastTargetServer()
  533. /*++
  534. Routine Description:
  535. Retrieves string for last server to which we tried to connect.
  536. Arguments:
  537. None.
  538. Return Values:
  539. VT_BSTR.
  540. --*/
  541. {
  542. if ( m_strLastTargetServer.IsEmpty() )
  543. return NULL;
  544. else
  545. return m_strLastTargetServer.AllocSysString();
  546. }
  547. void CApplication::SetLastTargetServer( LPCTSTR pszServerName )
  548. /*++
  549. Routine Description:
  550. Sets string for last server to which we tried to connect.
  551. Arguments:
  552. pszServerName - last server name to which we tried to connect.
  553. Return Values:
  554. None.
  555. --*/
  556. {
  557. m_strLastTargetServer = pszServerName;
  558. }