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.

812 lines
20 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*++
  3. Module Name:
  4. LsMgrDoc.cpp
  5. Abstract:
  6. This Module contains the implementation of CLicMgrDoc class
  7. (The Document class)
  8. Author:
  9. Arathi Kundapur (v-akunda) 11-Feb-1998
  10. Revision History:
  11. --*/
  12. #include "stdafx.h"
  13. #include "defines.h"
  14. #include "LicMgr.h"
  15. #include "LSMgrDoc.h"
  16. #include "LSServer.h"
  17. #include "MainFrm.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CLicMgrDoc
  25. IMPLEMENT_DYNCREATE(CLicMgrDoc, CDocument)
  26. BEGIN_MESSAGE_MAP(CLicMgrDoc, CDocument)
  27. //{{AFX_MSG_MAP(CLicMgrDoc)
  28. // NOTE - the ClassWizard will add and remove mapping macros here.
  29. // DO NOT EDIT what you see in these blocks of generated code!
  30. //}}AFX_MSG_MAP
  31. END_MESSAGE_MAP()
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CLicMgrDoc construction/destruction
  34. CLicMgrDoc::CLicMgrDoc()
  35. {
  36. // TODO: add one-time construction code here
  37. m_NodeType = NODE_NONE;
  38. m_pAllServers = NULL;
  39. }
  40. CLicMgrDoc::~CLicMgrDoc()
  41. {
  42. if(m_pAllServers)
  43. {
  44. delete m_pAllServers;
  45. m_pAllServers = NULL;
  46. }
  47. }
  48. BOOL CLicMgrDoc::OnNewDocument()
  49. {
  50. if (!CDocument::OnNewDocument())
  51. return FALSE;
  52. // TODO: add reinitialization code here
  53. // (SDI documents will reuse this document)
  54. return TRUE;
  55. }
  56. /////////////////////////////////////////////////////////////////////////////
  57. // CLicMgrDoc serialization
  58. void CLicMgrDoc::Serialize(CArchive& ar)
  59. {
  60. if (ar.IsStoring())
  61. {
  62. // TODO: add storing code here
  63. }
  64. else
  65. {
  66. // TODO: add loading code here
  67. }
  68. }
  69. /////////////////////////////////////////////////////////////////////////////
  70. // CLicMgrDoc diagnostics
  71. #ifdef _DEBUG
  72. void CLicMgrDoc::AssertValid() const
  73. {
  74. CDocument::AssertValid();
  75. }
  76. void CLicMgrDoc::Dump(CDumpContext& dc) const
  77. {
  78. CDocument::Dump(dc);
  79. }
  80. #endif //_DEBUG
  81. HRESULT CLicMgrDoc::EnumerateKeyPacks(CLicServer *pServer,DWORD dwSearchParm,BOOL bMatchAll)
  82. {
  83. ASSERT(pServer);
  84. HRESULT hResult = S_OK;
  85. if(pServer == NULL)
  86. return E_FAIL;
  87. if(TRUE == pServer->IsExpanded())
  88. return ALREADY_EXPANDED;
  89. PCONTEXT_HANDLE hBinding = NULL;
  90. BOOL bContext = FALSE;
  91. RPC_STATUS status;
  92. LSKeyPack keypack;
  93. DWORD dwErrCode;
  94. CString Server;
  95. hBinding = pServer->GetContext();
  96. if(NULL == hBinding)
  97. {
  98. if(pServer->UseIpAddress())
  99. Server = pServer->GetIpAddress();
  100. else
  101. Server = pServer->GetName();
  102. hBinding=TLSConnectToLsServer(Server.GetBuffer(Server.GetLength()));
  103. if(hBinding == NULL)
  104. {
  105. hResult = CONNECTION_FAILED;
  106. goto cleanup;
  107. }
  108. }
  109. memset(&keypack, 0, sizeof(keypack));
  110. keypack.dwLanguageId = GetUserDefaultUILanguage();
  111. status = TLSKeyPackEnumBegin(hBinding, dwSearchParm, bMatchAll, &keypack, &dwErrCode);
  112. if(status != RPC_S_OK || dwErrCode != ERROR_SUCCESS)
  113. {
  114. hResult = status;
  115. goto cleanup;
  116. }
  117. else
  118. {
  119. do
  120. {
  121. status = TLSKeyPackEnumNext(hBinding, &keypack, &dwErrCode);
  122. if(status == RPC_S_OK && dwErrCode == ERROR_SUCCESS)
  123. {
  124. DBGMSG( L"LICMGR:CLicMgrDoc::EnumerateKeyPacks - TLSKeyPackEnumNext\n" , 0 );
  125. CKeyPack * pKeyPack = new CKeyPack(keypack);
  126. if(pKeyPack == NULL)
  127. {
  128. hResult = E_OUTOFMEMORY;
  129. goto cleanup;
  130. }
  131. pServer->AddKeyPack(pKeyPack);
  132. }
  133. } while((status == RPC_S_OK) && (dwErrCode == ERROR_SUCCESS));
  134. TLSKeyPackEnumEnd(hBinding, &dwErrCode);
  135. pServer->Expand(TRUE);
  136. }
  137. cleanup:
  138. //put cleanup code here.
  139. if(hBinding)
  140. TLSDisconnectFromServer(&hBinding);
  141. return hResult;
  142. }
  143. HRESULT
  144. CLicMgrDoc::EnumerateLicenses(
  145. CKeyPack *pKeyPack,
  146. DWORD dwSearchParm,
  147. BOOL bMatchAll
  148. )
  149. /*++
  150. --*/
  151. {
  152. ASSERT(pKeyPack);
  153. if(NULL == pKeyPack)
  154. {
  155. return E_FAIL;
  156. }
  157. CLicServer *pServer = pKeyPack->GetServer();
  158. ASSERT(pServer);
  159. if(NULL == pKeyPack)
  160. {
  161. return E_FAIL;
  162. }
  163. HRESULT hResult = S_OK;
  164. if(TRUE == pKeyPack->IsExpanded())
  165. {
  166. return ALREADY_EXPANDED;
  167. }
  168. PCONTEXT_HANDLE hBinding = NULL;
  169. BOOL bContext = FALSE;
  170. DWORD status = ERROR_SUCCESS;
  171. LSLicenseEx sLicense;
  172. CString Server;
  173. hBinding = pServer->GetContext();
  174. if(NULL == hBinding)
  175. {
  176. if(pServer->UseIpAddress())
  177. {
  178. Server = pServer->GetIpAddress();
  179. }
  180. else
  181. {
  182. Server = pServer->GetName();
  183. }
  184. hBinding=TLSConnectToLsServer(Server.GetBuffer(Server.GetLength()));
  185. if(hBinding == NULL)
  186. {
  187. hResult = CONNECTION_FAILED;
  188. goto cleanup;
  189. }
  190. }
  191. memset(&sLicense, 0, sizeof(LSLicenseEx));
  192. sLicense.dwKeyPackId = pKeyPack->GetKeyPackStruct().dwKeyPackId;
  193. TLSLicenseEnumBegin( hBinding, dwSearchParm,bMatchAll ,(LPLSLicenseSearchParm) &sLicense, &status);
  194. if(status != ERROR_SUCCESS)
  195. {
  196. hResult = status;
  197. goto cleanup;
  198. }
  199. else
  200. {
  201. DWORD TLSLicenseEnumNextResult = ERROR_SUCCESS;
  202. do {
  203. memset(&sLicense, 0, sizeof(LSLicenseEx));
  204. sLicense.dwKeyPackId = pKeyPack->GetKeyPackStruct().dwKeyPackId;
  205. TLSLicenseEnumNextResult = TLSLicenseEnumNextEx(hBinding,&sLicense,&status);
  206. if ((status == ERROR_SUCCESS) && (TLSLicenseEnumNextResult == RPC_S_OK))
  207. {
  208. CLicense * pLicense = new CLicense(sLicense);
  209. if(NULL == pLicense)
  210. {
  211. hResult = E_OUTOFMEMORY;
  212. goto cleanup;
  213. }
  214. pKeyPack->AddIssuedLicense(pLicense);
  215. }
  216. } while ((status == ERROR_SUCCESS) && (TLSLicenseEnumNextResult == RPC_S_OK));
  217. TLSLicenseEnumEnd(hBinding,&status);
  218. pKeyPack->Expand(TRUE);
  219. }
  220. cleanup:
  221. //put cleanup code here
  222. if(hBinding)
  223. {
  224. TLSDisconnectFromServer(&hBinding);
  225. }
  226. return hResult;
  227. }
  228. DWORD
  229. GetPageSize( VOID ) {
  230. static DWORD dwPageSize = 0;
  231. if ( !dwPageSize ) {
  232. SYSTEM_INFO sysInfo = { 0 };
  233. GetSystemInfo( &sysInfo ); // cannot fail.
  234. dwPageSize = sysInfo.dwPageSize;
  235. }
  236. return dwPageSize;
  237. }
  238. /*++**************************************************************
  239. NAME: MyVirtualAlloc
  240. as Malloc, but automatically protects the last page of the
  241. allocation. This simulates pageheap behavior without requiring
  242. it.
  243. MODIFIES: ppvData -- receives memory
  244. TAKES: dwSize -- minimum amount of data to get
  245. RETURNS: TRUE when the function succeeds.
  246. FALSE otherwise.
  247. LASTERROR: not set
  248. Free with MyVirtualFree
  249. **************************************************************--*/
  250. BOOL
  251. MyVirtualAlloc( IN DWORD dwSize,
  252. OUT PVOID *ppvData )
  253. {
  254. PBYTE pbData;
  255. DWORD dwTotalSize;
  256. PVOID pvLastPage;
  257. // ensure that we allocate one extra page
  258. dwTotalSize = dwSize / GetPageSize();
  259. if( dwSize % GetPageSize() ) {
  260. dwTotalSize ++;
  261. }
  262. // this is the guard page
  263. dwTotalSize++;
  264. dwTotalSize *= GetPageSize();
  265. // do the alloc
  266. pbData = (PBYTE) VirtualAlloc( NULL, // don't care where
  267. dwTotalSize,
  268. MEM_COMMIT |
  269. MEM_TOP_DOWN,
  270. PAGE_READWRITE );
  271. if ( pbData ) {
  272. pbData += dwTotalSize;
  273. // find the LAST page.
  274. pbData -= GetPageSize();
  275. pvLastPage = pbData;
  276. // now, carve out a chunk for the caller:
  277. pbData -= dwSize;
  278. // last, protect the last page:
  279. if ( VirtualProtect( pvLastPage,
  280. 1, // protect the page containing the last byte
  281. PAGE_NOACCESS,
  282. &dwSize ) ) {
  283. *ppvData = pbData;
  284. return TRUE;
  285. }
  286. VirtualFree( pbData, 0, MEM_RELEASE );
  287. }
  288. return FALSE;
  289. }
  290. VOID
  291. MyVirtualFree( IN PVOID pvData )
  292. {
  293. VirtualFree( pvData, 0, MEM_RELEASE );
  294. }
  295. //
  296. // GetProcAddress needed because admin pack can install this binary on an
  297. // XP machine with an old mstlsapi.dll
  298. //
  299. typedef DWORD (WINAPI* PTLSGETSERVERNAMEFIXED) (
  300. TLS_HANDLE hHandle,
  301. LPTSTR *pszMachineName,
  302. PDWORD pdwErrCode
  303. );
  304. RPC_STATUS
  305. TryGetServerName(PCONTEXT_HANDLE hBinding,
  306. CString &Server)
  307. {
  308. RPC_STATUS status;
  309. DWORD dwErrCode;
  310. HINSTANCE hModule = LoadLibrary(L"mstlsapi.dll");
  311. if (hModule)
  312. {
  313. LPTSTR szMachineName = NULL;
  314. PTLSGETSERVERNAMEFIXED pfnGetServerNameFixed = (PTLSGETSERVERNAMEFIXED) GetProcAddress(hModule,"TLSGetServerNameFixed");
  315. if (pfnGetServerNameFixed)
  316. {
  317. status = pfnGetServerNameFixed(hBinding,&szMachineName,&dwErrCode);
  318. if(status == RPC_S_OK && dwErrCode == ERROR_SUCCESS && szMachineName != NULL)
  319. {
  320. Server = szMachineName;
  321. MIDL_user_free(szMachineName);
  322. FreeLibrary(hModule);
  323. return status;
  324. }
  325. }
  326. FreeLibrary(hModule);
  327. }
  328. {
  329. LPTSTR lpszMachineName = NULL;
  330. try
  331. {
  332. if ( !MyVirtualAlloc( ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ),
  333. (PVOID*) &lpszMachineName ) )
  334. {
  335. return RPC_S_OUT_OF_MEMORY;
  336. }
  337. DWORD uSize = MAX_COMPUTERNAME_LENGTH+1 ;
  338. memset(lpszMachineName, 0, ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ));
  339. status = TLSGetServerNameEx(hBinding,lpszMachineName,&uSize, &dwErrCode);
  340. if(status == RPC_S_OK && dwErrCode == ERROR_SUCCESS)
  341. {
  342. Server = lpszMachineName;
  343. }
  344. }
  345. catch(...)
  346. {
  347. status = ERROR_NOACCESS;
  348. }
  349. if( lpszMachineName )
  350. MyVirtualFree(lpszMachineName);
  351. }
  352. return status;
  353. }
  354. typedef DWORD (WINAPI* PTLSGETSERVERSCOPEFIXED) (
  355. TLS_HANDLE hHandle,
  356. LPTSTR *pszScopeName,
  357. PDWORD pdwErrCode
  358. );
  359. RPC_STATUS
  360. TryGetServerScope(PCONTEXT_HANDLE hBinding,
  361. CString &Scope)
  362. {
  363. RPC_STATUS status;
  364. DWORD dwErrCode;
  365. HINSTANCE hModule = LoadLibrary(L"mstlsapi.dll");
  366. if (hModule)
  367. {
  368. LPTSTR szServerScope = NULL;
  369. PTLSGETSERVERSCOPEFIXED pfnGetServerScopeFixed = (PTLSGETSERVERSCOPEFIXED) GetProcAddress(hModule,"TLSGetServerScopeFixed");
  370. if (pfnGetServerScopeFixed)
  371. {
  372. status = pfnGetServerScopeFixed(hBinding,&szServerScope,&dwErrCode);
  373. if(status == RPC_S_OK && dwErrCode == ERROR_SUCCESS && szServerScope != NULL)
  374. {
  375. Scope = szServerScope;
  376. MIDL_user_free(szServerScope);
  377. FreeLibrary(hModule);
  378. return status;
  379. }
  380. }
  381. FreeLibrary(hModule);
  382. }
  383. {
  384. LPTSTR lpszServerScope = NULL;
  385. try
  386. {
  387. if ( !MyVirtualAlloc( ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ),
  388. (PVOID*) &lpszServerScope ) )
  389. {
  390. return RPC_S_OUT_OF_MEMORY;
  391. }
  392. DWORD uSize = MAX_COMPUTERNAME_LENGTH+1 ;
  393. memset(lpszServerScope, 0, ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ));
  394. status = TLSGetServerScope(hBinding, lpszServerScope, &uSize, &dwErrCode);
  395. if(status == RPC_S_OK && dwErrCode == ERROR_SUCCESS)
  396. {
  397. Scope = lpszServerScope;
  398. }
  399. }
  400. catch(...)
  401. {
  402. status = ERROR_NOACCESS;
  403. }
  404. if(lpszServerScope)
  405. MyVirtualFree(lpszServerScope);
  406. }
  407. return status;
  408. }
  409. HRESULT
  410. CLicMgrDoc::ConnectToServer(
  411. CString& Server,
  412. CString& Scope,
  413. SERVER_TYPE& ServerType
  414. )
  415. /*++
  416. --*/
  417. {
  418. PCONTEXT_HANDLE hBinding = NULL;
  419. HRESULT hResult = ERROR_SUCCESS;
  420. RPC_STATUS status;
  421. LPTSTR szServerScope = NULL;
  422. LPTSTR szMachineName = NULL;
  423. DWORD dwVersion = 0;
  424. PBYTE pbData = NULL;
  425. DWORD cbData = 0;
  426. DWORD dwErrCode;
  427. hBinding = TLSConnectToLsServer(Server.GetBuffer(Server.GetLength()));
  428. if(hBinding == NULL)
  429. {
  430. hResult = E_FAIL;
  431. goto cleanup;
  432. }
  433. TryGetServerName(hBinding,Server);
  434. Scope.Empty();
  435. status = TryGetServerScope(hBinding,Scope);
  436. if(status != RPC_S_OK || Scope.IsEmpty())
  437. {
  438. Scope.LoadString(IDS_UNKNOWN);
  439. }
  440. //Get whether this is a TS4 server or TS5Enforced or TS5NonEnforced
  441. status = TLSGetVersion (hBinding, &dwVersion);
  442. if(status == RPC_S_OK)
  443. {
  444. if(dwVersion & 0x40000000)
  445. {
  446. ServerType = SERVER_TS5_ENFORCED;
  447. }
  448. else
  449. {
  450. ServerType = SERVER_TS5_NONENFORCED;
  451. }
  452. }
  453. else if(status == RPC_S_UNKNOWN_IF)
  454. {
  455. ServerType = SERVER_TS4;
  456. Scope = Server ;
  457. }
  458. else
  459. {
  460. hResult = E_FAIL;
  461. }
  462. cleanup:
  463. if(pbData != NULL)
  464. {
  465. midl_user_free(pbData);
  466. }
  467. if(hBinding)
  468. {
  469. TLSDisconnectFromServer(&hBinding);
  470. }
  471. return hResult;
  472. }
  473. HRESULT CLicMgrDoc::ConnectWithCurrentParams()
  474. {
  475. CLicMgrApp *pApp = (CLicMgrApp*)AfxGetApp();
  476. CMainFrame * pWnd = (CMainFrame *)pApp->m_pMainWnd ;
  477. HRESULT hResult = ERROR_SUCCESS;
  478. CString Scope;
  479. CString IpAddress;
  480. CString Server = pApp->m_Server;
  481. if(NULL == m_pAllServers)
  482. m_pAllServers = new CAllServers(_T(""));
  483. if(NULL == m_pAllServers)
  484. {
  485. hResult = E_OUTOFMEMORY;
  486. goto cleanup;
  487. }
  488. pWnd->SendMessage(WM_ADD_ALL_SERVERS,0,(LPARAM)m_pAllServers);
  489. if(!Server.IsEmpty())
  490. {
  491. if(TRUE == IsServerInList(Server))
  492. {
  493. hResult = E_DUPLICATE;
  494. }
  495. if( hResult == ERROR_SUCCESS )
  496. {
  497. pWnd->ConnectServer( Server );
  498. }
  499. /* Why did we have this here?
  500. IpAddress = Server;
  501. hResult = ConnectToServer(
  502. Server,
  503. Scope,
  504. ServerType
  505. );
  506. if(ERROR_SUCCESS == hResult)
  507. {
  508. CAllServers * pAllServers = m_pAllServers;
  509. CLicServer *pServer1 = NULL;
  510. if(IpAddress != Server)
  511. {
  512. if(TRUE == IsServerInList(Server))
  513. {
  514. hResult = E_DUPLICATE;
  515. goto cleanup;
  516. }
  517. pServer1 = new CLicServer(Server,ServerType,Scope,IpAddress);
  518. }
  519. else
  520. {
  521. pServer1 = new CLicServer(Server,ServerType,Scope);
  522. }
  523. if(pServer1)
  524. {
  525. pAllServers->AddLicServer(pServer1);
  526. pWnd->SendMessage(WM_ADD_SERVER,0,(LPARAM)pServer1);
  527. }
  528. else
  529. {
  530. return E_OUTOFMEMORY;
  531. }
  532. }
  533. */
  534. }
  535. cleanup:
  536. //Add any cleanup code required here.
  537. return hResult;
  538. }
  539. void CLicMgrDoc:: TimeToString(DWORD *ptime, CString& rString)
  540. {
  541. TCHAR m_szTime[MAX_PATH];
  542. time_t time;
  543. rString.Empty();
  544. ASSERT(ptime);
  545. if(NULL == ptime)
  546. return;
  547. //
  548. // Times are stored in the ANSI time_t style in the database,
  549. // however they are type cast to a DWORD (unsigned long). Because
  550. // time_t is 64 bit on a 64 bit machine, and because it is a signed
  551. // value, we must be careful here to make sure that the sign of the
  552. // value is not lost as the value goes from 32 to 64 bit.
  553. //
  554. time = (time_t)(LONG)(*ptime);
  555. LPTSTR lpszTime = NULL;
  556. //Getting the local time as the time is stored as GMT
  557. //in the license server database.
  558. struct tm * pTm = localtime(&time);
  559. if(NULL == pTm)
  560. return;
  561. SYSTEMTIME SystemTime;
  562. SystemTime.wYear = (WORD)(pTm->tm_year + 1900);
  563. SystemTime.wMonth = (WORD)(pTm->tm_mon + 1);
  564. SystemTime.wDayOfWeek = (WORD)pTm->tm_wday;
  565. SystemTime.wDay = (WORD)pTm->tm_mday;
  566. SystemTime.wHour = (WORD)pTm->tm_hour;
  567. SystemTime.wMinute = (WORD)pTm->tm_min;
  568. SystemTime.wSecond = (WORD)pTm->tm_sec;
  569. SystemTime.wMilliseconds = 0;
  570. int RetLen;
  571. TCHAR DateFormat[MAX_PATH];
  572. TCHAR TimeFormat[MAX_PATH];
  573. RetLen = ::GetLocaleInfo(LOCALE_USER_DEFAULT,
  574. LOCALE_SLONGDATE,
  575. DateFormat,
  576. sizeof(DateFormat)/sizeof(TCHAR));
  577. ASSERT(RetLen!=0);
  578. RetLen = ::GetLocaleInfo(LOCALE_USER_DEFAULT,
  579. LOCALE_STIMEFORMAT,
  580. TimeFormat,
  581. sizeof(TimeFormat)/sizeof(TCHAR));
  582. ASSERT(RetLen!=0);
  583. RetLen = ::GetDateFormat(LOCALE_USER_DEFAULT,
  584. 0, /* dwFlag */
  585. &SystemTime,
  586. DateFormat, /* lpFormat */
  587. m_szTime,
  588. sizeof(m_szTime)/sizeof(TCHAR));
  589. if (RetLen == 0)
  590. return;
  591. _tcscat(m_szTime, _T(" ")); /* Separator of date and time */
  592. lpszTime = &m_szTime[lstrlen(m_szTime)];
  593. RetLen = ::GetTimeFormat(LOCALE_USER_DEFAULT,
  594. 0, /* dwFlag */
  595. &SystemTime,
  596. TimeFormat, /* lpFormat */
  597. lpszTime,
  598. sizeof(m_szTime)/sizeof(TCHAR) - lstrlen(m_szTime));
  599. if (RetLen == 0)
  600. return;
  601. rString = m_szTime;
  602. return;
  603. }
  604. BOOL CLicMgrDoc::IsServerInList(CString & Server)
  605. {
  606. ASSERT(m_pAllServers);
  607. if(NULL == m_pAllServers)
  608. return FALSE;
  609. BOOL bServerInList = FALSE;
  610. LicServerList * pServerList = m_pAllServers->GetLicServerList();
  611. //Assumption: ServerName is unique
  612. POSITION pos = pServerList->GetHeadPosition();
  613. while(pos)
  614. {
  615. CLicServer *pLicServer = (CLicServer *)pServerList->GetNext(pos);
  616. ASSERT(pLicServer);
  617. if(NULL == pLicServer)
  618. continue;
  619. if((0 == Server.CompareNoCase(pLicServer->GetName())) || (0 == Server.CompareNoCase(pLicServer->GetIpAddress())))
  620. {
  621. bServerInList = TRUE;
  622. break;
  623. }
  624. }
  625. return bServerInList;
  626. }