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.

1580 lines
40 KiB

  1. // tslsview.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. //#include "resource.h"
  5. extern "C" {
  6. BOOL OpenLog(VOID);
  7. VOID LogMsg(PWCHAR msgFormat, ...);
  8. BOOL LogDiagnosisFile( LPTSTR );
  9. VOID CloseLog(VOID);
  10. }
  11. //=---------globals------------
  12. static HINSTANCE g_hinst;
  13. static BOOL g_fInitialized;
  14. ServerEnumData g_sed;
  15. PLIST g_pHead;
  16. static HANDLE g_hEvent;
  17. static BOOL g_bAutomaticLog;
  18. BOOL g_bDiagnosticLog = FALSE;
  19. static DWORD g_dwInterval = 1000 * 60 * 5;
  20. static BOOL g_bLog = 1;
  21. TCHAR szLsViewKey[] = TEXT( "Software\\Microsoft\\Windows NT\\CurrentVersion\\LsView" );
  22. //-----------------------------
  23. //-------------function prototypes ----------------
  24. INT_PTR CALLBACK Dlg_Proc( HWND hwnd , UINT msg , WPARAM wp, LPARAM lp );
  25. BOOL OnInitApp( HWND );
  26. void OnTimedEvent( HWND hDlg );
  27. DWORD DiscoverServers( LPVOID ptr );
  28. BOOL ServerEnumCallBack( TLS_HANDLE hHandle,
  29. LPCTSTR pszServerName,
  30. HANDLE dwUserData );
  31. void OnReSize( HWND hwnd ,
  32. WPARAM wp ,
  33. LPARAM lp );
  34. BOOL DeleteList( PLIST );
  35. BOOL AddItem( LPTSTR , LPTSTR , LPTSTR );
  36. void CreateLogFile( HWND );
  37. BOOL Tray_Init( HWND hwnd , BOOL );
  38. BOOL Tray_ToGreen( HWND hwnd );
  39. BOOL Tray_ToYellow( HWND hwnd , LPTSTR szMsg );
  40. BOOL Tray_ToRed( HWND hwnd );
  41. BOOL Tray_Remove( HWND hwnd );
  42. BOOL Tray_ToXXX( HWND hwnd , LPTSTR szTip , UINT resid );
  43. BOOL Tray_Notify( HWND hwnd , WPARAM wp , LPARAM lp );
  44. UINT_PTR CALLBACK OFNHookProc( HWND hdlg , UINT uiMsg, WPARAM wParam, LPARAM lParam );
  45. BOOL RetrieveDataObject( PDATAOBJECT pObj );
  46. BOOL StoreDataObject( PDATAOBJECT pObj );
  47. BOOL LogFile( LPTSTR szFileName );
  48. //-------------------------------------------------
  49. //=---------constants------------
  50. const UINT kTimerId = 23456;
  51. const UINT kDefaultElapseTime = 1000 * 60 * 5;
  52. const UINT kMaxMinutes = 71582;
  53. const UINT kBubbleTimeout = 10 * 1000;
  54. #define TN_MESSAGE ( WM_USER + 60 )
  55. //-----------------------------
  56. DWORD
  57. GetPageSize( VOID ) {
  58. static DWORD dwPageSize = 0;
  59. if ( !dwPageSize ) {
  60. SYSTEM_INFO sysInfo = { 0 };
  61. GetSystemInfo( &sysInfo ); // cannot fail.
  62. dwPageSize = sysInfo.dwPageSize;
  63. }
  64. return dwPageSize;
  65. }
  66. /*++**************************************************************
  67. NAME: MyVirtualAlloc
  68. as Malloc, but automatically protects the last page of the
  69. allocation. This simulates pageheap behavior without requiring
  70. it.
  71. MODIFIES: ppvData -- receives memory
  72. TAKES: dwSize -- minimum amount of data to get
  73. RETURNS: TRUE when the function succeeds.
  74. FALSE otherwise.
  75. LASTERROR: not set
  76. Free with MyVirtualFree
  77. **************************************************************--*/
  78. BOOL
  79. MyVirtualAlloc( IN DWORD dwSize,
  80. OUT PVOID *ppvData )
  81. {
  82. PBYTE pbData;
  83. DWORD dwTotalSize;
  84. PVOID pvLastPage;
  85. // ensure that we allocate one extra page
  86. dwTotalSize = dwSize / GetPageSize();
  87. if( dwSize % GetPageSize() ) {
  88. dwTotalSize ++;
  89. }
  90. // this is the guard page
  91. dwTotalSize++;
  92. dwTotalSize *= GetPageSize();
  93. // do the alloc
  94. pbData = (PBYTE) VirtualAlloc( NULL, // don't care where
  95. dwTotalSize,
  96. MEM_COMMIT |
  97. MEM_TOP_DOWN,
  98. PAGE_READWRITE );
  99. if ( pbData ) {
  100. pbData += dwTotalSize;
  101. // find the LAST page.
  102. pbData -= GetPageSize();
  103. pvLastPage = pbData;
  104. // now, carve out a chunk for the caller:
  105. pbData -= dwSize;
  106. // last, protect the last page:
  107. if ( VirtualProtect( pvLastPage,
  108. 1, // protect the page containing the last byte
  109. PAGE_NOACCESS,
  110. &dwSize ) ) {
  111. *ppvData = pbData;
  112. return TRUE;
  113. }
  114. VirtualFree( pbData, 0, MEM_RELEASE );
  115. }
  116. return FALSE;
  117. }
  118. VOID
  119. MyVirtualFree( IN PVOID pvData )
  120. {
  121. VirtualFree( pvData, 0, MEM_RELEASE );
  122. }
  123. //-------------------------------------------------------------------------
  124. int APIENTRY WinMain(HINSTANCE hInstance,
  125. HINSTANCE hPrevInstance,
  126. LPSTR lpCmdLine,
  127. int nCmdShow)
  128. {
  129. INITCOMMONCONTROLSEX icc = { sizeof( INITCOMMONCONTROLSEX ) ,
  130. ICC_LISTVIEW_CLASSES };
  131. HANDLE hMutex = CreateMutex( NULL , FALSE , TEXT("TSLSVIEW2" ) );
  132. if( GetLastError() == ERROR_ALREADY_EXISTS )
  133. {
  134. TCHAR szTitle[ 60 ];
  135. DBGMSG( TEXT( "TSLSVIEW: App instance already running\n" ) , 0 );
  136. LoadString( hInstance ,
  137. IDS_TITLE ,
  138. szTitle ,
  139. SIZEOF( szTitle ) );
  140. HWND hWnd = FindWindow( NULL , szTitle );
  141. if( hWnd != NULL )
  142. {
  143. SetForegroundWindow( hWnd );
  144. }
  145. return 0;
  146. }
  147. if( !InitCommonControlsEx( &icc ) )
  148. {
  149. DBGMSG( TEXT("InitCommonControlsEx failed with 0x%x\n") , GetLastError( ) );
  150. return 0;
  151. }
  152. g_hinst = hInstance;
  153. g_fInitialized = FALSE;
  154. g_hEvent = CreateEvent( NULL , FALSE , TRUE , NULL );
  155. if(OpenLog() == FALSE)
  156. {
  157. ODS(TEXT("Failed to open temporary file for discovery diagnostics"));
  158. return 0;
  159. }
  160. g_pHead = ( PLIST )new LIST[1];
  161. if( g_pHead == NULL )
  162. {
  163. ODS( TEXT( "LSVIEW out of memory\n" ) );
  164. return 0;
  165. }
  166. g_pHead->pszMachineName = NULL;
  167. g_pHead->pszTimeFormat = NULL;
  168. g_pHead->pszType = NULL;
  169. g_pHead->pNext = NULL;
  170. DialogBox( hInstance ,
  171. MAKEINTRESOURCE( IDD_LSVIEW ),
  172. NULL,
  173. Dlg_Proc);
  174. CloseHandle( hMutex );
  175. CloseHandle( g_hEvent );
  176. DeleteList( g_pHead );
  177. CloseLog();
  178. return 0;
  179. }
  180. //-------------------------------------------------------------------------
  181. INT_PTR CALLBACK Dlg_Proc( HWND hwnd , UINT msg , WPARAM wp, LPARAM lp )
  182. {
  183. TCHAR szTitle[ 60 ];
  184. switch( msg )
  185. {
  186. case WM_COMMAND:
  187. switch( LOWORD( wp ) )
  188. {
  189. case ID_FILE_EXIT:
  190. EndDialog( hwnd , 0 );
  191. break;
  192. case ID_FILE_CREATELOGFILE:
  193. if( WaitForSingleObject( g_hEvent , 0 ) == WAIT_TIMEOUT )
  194. {
  195. TCHAR szBuffer[ 255 ];
  196. LoadString( g_hinst ,
  197. IDS_ERROR_QS ,
  198. szBuffer ,
  199. SIZEOF( szBuffer )
  200. );
  201. LoadString( g_hinst ,
  202. IDS_TITLE ,
  203. szTitle ,
  204. SIZEOF( szTitle )
  205. );
  206. MessageBox( hwnd , szBuffer, szTitle , MB_OK | MB_ICONINFORMATION );
  207. }
  208. else
  209. {
  210. SetEvent( g_hEvent );
  211. CreateLogFile( hwnd );
  212. }
  213. break;
  214. case ID_HELP_ABOUT:
  215. LoadString( g_hinst ,
  216. IDS_TITLE ,
  217. szTitle ,
  218. SIZEOF( szTitle )
  219. );
  220. ShellAbout( hwnd ,
  221. szTitle ,
  222. NULL ,
  223. LoadIcon( g_hinst , MAKEINTRESOURCE( IDI_TSLSVIEW ) )
  224. );
  225. break;
  226. case IDM_MINIMIZE:
  227. ShowWindow( hwnd , SW_MINIMIZE );
  228. break;
  229. case IDM_RESTORE:
  230. ShowWindow( hwnd , SW_RESTORE );
  231. break;
  232. case IDM_EXIT:
  233. DestroyWindow( hwnd );
  234. break;
  235. }
  236. break;
  237. case WM_CLOSE:
  238. case WM_DESTROY:
  239. Tray_ToRed( hwnd );
  240. KillTimer( hwnd , kTimerId );
  241. Tray_Remove( hwnd );
  242. EndDialog( hwnd , 0 );
  243. break;
  244. case WM_INITDIALOG:
  245. OnInitApp( hwnd );
  246. break;
  247. case WM_TIMER:
  248. if( wp == ( WPARAM )kTimerId )
  249. {
  250. OnTimedEvent( hwnd );
  251. }
  252. break;
  253. case WM_SIZE:
  254. OnReSize( hwnd , wp , lp );
  255. break;
  256. case TN_MESSAGE:
  257. Tray_Notify( hwnd , wp , lp );
  258. break;
  259. }
  260. return FALSE;
  261. }
  262. //-------------------------------------------------------------------------
  263. BOOL InitListView( HWND hwnd )
  264. {
  265. int rgIds[] = { IDS_STR_COL1 ,
  266. IDS_STR_COL2 ,
  267. IDS_STR_COL3 ,
  268. -1 };
  269. LV_COLUMN lvc;
  270. TCHAR tchBuffer[ 60 ];
  271. HWND hListView = GetDlgItem( hwnd , IDC_LSVIEW_LIST ) ;
  272. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  273. lvc.fmt = LVCFMT_LEFT;
  274. for( int idx=0; rgIds[idx] != -1; ++idx )
  275. {
  276. LoadString( g_hinst ,
  277. ( UINT )rgIds[idx],
  278. tchBuffer,
  279. SIZEOF( tchBuffer ) );
  280. if( idx == 1 )
  281. {
  282. lvc.cx = 225;
  283. }
  284. else
  285. {
  286. lvc.cx = 75;
  287. }
  288. lvc.pszText = tchBuffer;
  289. lvc.iSubItem = idx;
  290. ListView_InsertColumn( hListView ,
  291. idx ,
  292. &lvc );
  293. }
  294. DWORD dwStyle = ( DWORD )SendMessage( hListView ,
  295. LVM_GETEXTENDEDLISTVIEWSTYLE ,
  296. 0 ,
  297. 0 );
  298. dwStyle |= ( LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES ) ;
  299. SendMessage( hListView , LVM_SETEXTENDEDLISTVIEWSTYLE , 0 , dwStyle );
  300. return TRUE;
  301. }
  302. //-------------------------------------------------------------------------
  303. BOOL OnInitApp( HWND hwnd )
  304. {
  305. DATAOBJECT dobj;
  306. // set up listview extended mode
  307. InitListView( hwnd );
  308. LONG_PTR lptrIcon;
  309. lptrIcon = ( LONG_PTR )LoadImage( g_hinst ,
  310. MAKEINTRESOURCE( IDI_TSLSVIEW ),
  311. IMAGE_ICON,
  312. 16,
  313. 16,
  314. 0
  315. );
  316. SetClassLongPtr( hwnd , GCLP_HICONSM , lptrIcon );
  317. lptrIcon = ( LONG_PTR )LoadImage( g_hinst ,
  318. MAKEINTRESOURCE( IDI_TSLSVIEW ),
  319. IMAGE_ICON,
  320. 0,
  321. 0,
  322. 0
  323. );
  324. SetClassLongPtr( hwnd , GCLP_HICON , lptrIcon );
  325. ZeroMemory( &dobj , sizeof( dobj ) );
  326. if( RetrieveDataObject( &dobj ) )
  327. {
  328. g_bAutomaticLog = dobj.bIsChecked;
  329. g_bDiagnosticLog = dobj.bIsDiagnosisChecked;
  330. g_dwInterval = dobj.dwTimeInterval * 1000 * 60;
  331. }
  332. if( dobj.dwTimeInterval == 0 )
  333. {
  334. g_dwInterval = ( DWORD )kDefaultElapseTime;
  335. }
  336. // setup initial trayicon
  337. Tray_Init( hwnd , dobj.bNotifyOnce );
  338. if( !dobj.bNotifyOnce )
  339. {
  340. dobj.bNotifyOnce = TRUE;
  341. StoreDataObject( &dobj );
  342. }
  343. // set cursor to hourglass
  344. OnTimedEvent( hwnd );
  345. SetTimer( hwnd ,
  346. kTimerId,
  347. g_dwInterval,
  348. NULL
  349. );
  350. return TRUE;
  351. }
  352. //-------------------------------------------------------------------------
  353. void OnTimedEvent( HWND hDlg )
  354. {
  355. ODS( L"LSVIEW: OnTimedEvent fired " );
  356. g_sed.dwNumServer = 0;
  357. g_sed.dwDone = 0;
  358. g_sed.hList = GetDlgItem( hDlg , IDC_LSVIEW_LIST );
  359. // remove all listview items
  360. DWORD dwValue;
  361. dwValue = WaitForSingleObject( g_hEvent , 0 );
  362. if( dwValue == WAIT_TIMEOUT )
  363. {
  364. ODS( TEXT("still looking for servers\n" ) );
  365. return;
  366. }
  367. SetEvent( g_hEvent );
  368. ODS( TEXT("launching thread\n" ) );
  369. HANDLE hThread = CreateThread( NULL ,
  370. 0 ,
  371. ( LPTHREAD_START_ROUTINE )DiscoverServers,
  372. ( LPVOID )&g_sed ,
  373. 0,
  374. &dwValue
  375. );
  376. if( hThread == NULL )
  377. {
  378. DBGMSG( TEXT( "Failed to create DiscoverServer thread last error 0x%x\n" ) , GetLastError( ) );
  379. Tray_ToRed( hDlg );
  380. }
  381. CloseHandle( hThread );
  382. }
  383. //-------------------------------------------------------------------------
  384. DWORD DiscoverServers( LPVOID ptr )
  385. {
  386. WaitForSingleObject( g_hEvent , INFINITE );
  387. ODS( L"LSVIEW -- entering DiscoverServers\n" );
  388. if (!g_fInitialized)
  389. {
  390. TLSInit();
  391. g_fInitialized = TRUE;
  392. }
  393. LPWSTR *ppszEnterpriseServer = NULL;
  394. DWORD dwCount;
  395. DWORD index;
  396. // we could be writing out to a file we should wait
  397. if( g_pHead != NULL )
  398. {
  399. DeleteList( g_pHead->pNext );
  400. g_pHead->pNext = NULL;
  401. }
  402. //
  403. // Look for all license servers in domain
  404. //
  405. ServerEnumData *pEnumData = ( ServerEnumData * )ptr;
  406. TCHAR szBuffer[ 60 ];
  407. LoadString( g_hinst ,
  408. IDS_YELLOW ,
  409. szBuffer ,
  410. SIZEOF( szBuffer )
  411. );
  412. Tray_ToYellow( GetParent( pEnumData->hList ) , szBuffer );
  413. HRESULT hResult = EnumerateTlsServer(
  414. ServerEnumCallBack,
  415. ptr,
  416. 3000,
  417. FALSE
  418. );
  419. hResult = GetAllEnterpriseServers(
  420. &ppszEnterpriseServer,
  421. &dwCount
  422. );
  423. if( hResult == ERROR_SUCCESS && dwCount != 0 && ppszEnterpriseServer != NULL )
  424. {
  425. TLS_HANDLE TlsHandle = NULL;
  426. //
  427. // Inform dialog
  428. //
  429. for(index = 0; index < dwCount && pEnumData->dwDone == 0; index++)
  430. {
  431. if( ppszEnterpriseServer[index] == NULL )
  432. {
  433. continue;
  434. }
  435. if(ServerEnumCallBack(
  436. NULL,
  437. (LPTSTR)ppszEnterpriseServer[index],
  438. pEnumData ) == TRUE
  439. )
  440. {
  441. continue;
  442. }
  443. TlsHandle = TLSConnectToLsServer(
  444. (LPTSTR)ppszEnterpriseServer[index]
  445. );
  446. if(TlsHandle == NULL )
  447. {
  448. continue;
  449. if(g_bLog)
  450. LogMsg(L"Can't connect to %s. Maybe it has no License Service running on it.\n", (LPTSTR)ppszEnterpriseServer[index]);
  451. }
  452. if(g_bLog)
  453. LogMsg(L"!!!Connected to License Service on %s\n",(LPTSTR)ppszEnterpriseServer[index]);
  454. ServerEnumCallBack( TlsHandle,
  455. (LPTSTR)ppszEnterpriseServer[index],
  456. pEnumData
  457. );
  458. TLSDisconnectFromServer(TlsHandle);
  459. }
  460. if( ppszEnterpriseServer != NULL )
  461. {
  462. for( index = 0; index < dwCount; index ++)
  463. {
  464. if( ppszEnterpriseServer[ index ] != NULL )
  465. {
  466. LocalFree( ppszEnterpriseServer[ index ] );
  467. }
  468. }
  469. LocalFree( ppszEnterpriseServer );
  470. }
  471. }
  472. ListView_DeleteAllItems( pEnumData->hList );
  473. PLIST pTemp;
  474. if( g_pHead != NULL )
  475. {
  476. pTemp = g_pHead->pNext;
  477. while( pTemp != NULL )
  478. {
  479. int nItem = ListView_GetItemCount( pEnumData->hList );
  480. LVITEM lvi;
  481. ZeroMemory( &lvi , sizeof( LVITEM ) );
  482. lvi.mask = LVIF_TEXT;
  483. lvi.pszText = pTemp->pszMachineName;
  484. lvi.cchTextMax = lstrlen( pTemp->pszMachineName );
  485. lvi.iItem = nItem;
  486. lvi.iSubItem = 0;
  487. ListView_InsertItem( pEnumData->hList ,
  488. &lvi
  489. );
  490. // Set item for second column
  491. lvi.pszText = pTemp->pszTimeFormat;
  492. lvi.iSubItem = 1;
  493. lvi.cchTextMax = sizeof( pTemp->pszTimeFormat );
  494. ListView_SetItem( pEnumData->hList ,
  495. &lvi
  496. );
  497. // Set item for third column
  498. lvi.pszText = pTemp->pszType;
  499. lvi.iSubItem = 2;
  500. lvi.cchTextMax = sizeof( pTemp->pszType );
  501. ListView_SetItem( pEnumData->hList ,
  502. &lvi
  503. );
  504. pTemp = pTemp->pNext;
  505. }
  506. }
  507. if( g_bAutomaticLog )
  508. {
  509. DATAOBJECT db;
  510. ZeroMemory( &db , sizeof( DATAOBJECT ) );
  511. if( RetrieveDataObject( &db ) )
  512. {
  513. if( g_bDiagnosticLog )
  514. LogDiagnosisFile( db.wchFileName );
  515. else
  516. LogFile( db.wchFileName );
  517. }
  518. }
  519. ODS( L"LSVIEW : DiscoverServers completing\n" );
  520. // motion for green
  521. Tray_ToGreen( GetParent( pEnumData->hList ) );
  522. SetEvent( g_hEvent );
  523. ExitThread( hResult );
  524. return ( DWORD )hResult;
  525. }
  526. typedef DWORD (WINAPI* PTLSGETSERVERNAMEFIXED) (
  527. TLS_HANDLE hHandle,
  528. LPTSTR *pszMachineName,
  529. PDWORD pdwErrCode
  530. );
  531. typedef DWORD (WINAPI* PTLSGETSERVERNAMEEX) (
  532. TLS_HANDLE hHandle,
  533. LPTSTR pszMachineName,
  534. PDWORD pdwSize,
  535. PDWORD pdwErrCode
  536. );
  537. RPC_STATUS
  538. TryGetServerName(PCONTEXT_HANDLE hBinding,
  539. LPTSTR *pszServer)
  540. {
  541. RPC_STATUS status;
  542. DWORD dwErrCode;
  543. HINSTANCE hModule = LoadLibrary(L"mstlsapi.dll");
  544. if (hModule)
  545. {
  546. PTLSGETSERVERNAMEFIXED pfnGetServerNameFixed = (PTLSGETSERVERNAMEFIXED) GetProcAddress(hModule,"TLSGetServerNameFixed");
  547. if (pfnGetServerNameFixed)
  548. {
  549. status = pfnGetServerNameFixed(hBinding,pszServer,&dwErrCode);
  550. if(status == RPC_S_OK && dwErrCode == ERROR_SUCCESS && pszServer != NULL)
  551. {
  552. FreeLibrary(hModule);
  553. return status;
  554. }
  555. }
  556. LPTSTR lpszMachineName = NULL;
  557. try
  558. {
  559. if ( !MyVirtualAlloc( ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ),
  560. (PVOID*) &lpszMachineName ) )
  561. {
  562. return RPC_S_OUT_OF_MEMORY;
  563. }
  564. DWORD uSize = MAX_COMPUTERNAME_LENGTH+1 ;
  565. memset(lpszMachineName, 0, ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ));
  566. PTLSGETSERVERNAMEEX pfnGetServerNameEx = (PTLSGETSERVERNAMEEX) GetProcAddress(hModule,"TLSGetServerNameEx");
  567. if (pfnGetServerNameEx != NULL)
  568. {
  569. status = pfnGetServerNameEx(hBinding,lpszMachineName,&uSize, &dwErrCode);
  570. if(status == RPC_S_OK && dwErrCode == ERROR_SUCCESS)
  571. {
  572. *pszServer = (LPTSTR) MIDL_user_allocate((lstrlen(lpszMachineName)+1)*sizeof(TCHAR));
  573. if (NULL != *pszServer)
  574. {
  575. lstrcpy(*pszServer,lpszMachineName);
  576. }
  577. }
  578. }
  579. }
  580. catch (...)
  581. {
  582. status = ERROR_NOACCESS;
  583. }
  584. if(lpszMachineName)
  585. MyVirtualFree(lpszMachineName);
  586. if(hModule)
  587. FreeLibrary(hModule);
  588. }
  589. return status;
  590. }
  591. //-------------------------------------------------------------------------
  592. BOOL ServerEnumCallBack( TLS_HANDLE hHandle,
  593. LPCTSTR pszServerName,
  594. HANDLE dwUserData )
  595. {
  596. int i;
  597. ServerEnumData* pEnumData = (ServerEnumData *)dwUserData;
  598. BOOL bCancel;
  599. if( pEnumData == NULL )
  600. {
  601. return FALSE;
  602. }
  603. bCancel = ( InterlockedExchange( &(pEnumData->dwDone) ,
  604. pEnumData->dwDone) == 1);
  605. if( bCancel == TRUE )
  606. {
  607. return TRUE;
  608. }
  609. if( hHandle != NULL )
  610. {
  611. DWORD dwStatus;
  612. DWORD dwErrCode;
  613. DWORD dwVersion;
  614. LPTSTR szServer = NULL;
  615. TCHAR szMcType[ MAX_COMPUTERNAME_LENGTH + 1 ];
  616. TCHAR szTimeFormat[ 256 ];
  617. DWORD dwBufSize = SIZEOF( szServer);
  618. dwStatus = TryGetServerName( hHandle,
  619. &szServer
  620. );
  621. if( dwStatus != ERROR_SUCCESS || szServer == NULL )
  622. {
  623. return FALSE;
  624. }
  625. TLSGetVersion(hHandle, &dwVersion);
  626. if( dwVersion & TLS_VERSION_ENTERPRISE_BIT )
  627. {
  628. LoadString( g_hinst ,
  629. IDS_TYPE_ENT,
  630. szMcType,
  631. SIZEOF( szMcType ) );
  632. }
  633. else
  634. {
  635. LoadString( g_hinst ,
  636. IDS_TYPE_DOMAIN,
  637. szMcType,
  638. SIZEOF( szMcType ) );
  639. }
  640. SYSTEMTIME st;
  641. TCHAR szDate[ 80 ];
  642. TCHAR szTime[ 80 ];
  643. GetLocalTime( &st );
  644. GetDateFormat( LOCALE_USER_DEFAULT ,
  645. DATE_LONGDATE ,
  646. &st,
  647. NULL,
  648. szDate,
  649. SIZEOF( szDate ) );
  650. GetTimeFormat( LOCALE_USER_DEFAULT,
  651. TIME_NOSECONDS,
  652. &st,
  653. NULL,
  654. szTime,
  655. SIZEOF( szTime ) );
  656. wsprintf( szTimeFormat , TEXT( "%s %s") , szDate , szTime );
  657. AddItem( szServer , szTimeFormat , szMcType );
  658. pEnumData->dwNumServer++;
  659. MIDL_user_free(szServer);
  660. }
  661. //
  662. // Continue enumeration
  663. //
  664. return InterlockedExchange(&(pEnumData->dwDone), pEnumData->dwDone) == 1;
  665. }
  666. //-------------------------------------------------------------------------
  667. void OnReSize( HWND hwnd , WPARAM wp , LPARAM lp )
  668. {
  669. HWND hList = GetDlgItem( hwnd , IDC_LSVIEW_LIST );
  670. if( hList != NULL )
  671. {
  672. MoveWindow( hList ,
  673. 0 ,
  674. 0 ,
  675. LOWORD( lp ),
  676. HIWORD( lp ) ,
  677. TRUE
  678. );
  679. if( wp == SIZE_RESTORED || wp == SIZE_MAXIMIZED )
  680. {
  681. ListView_RedrawItems( hList ,
  682. 0 ,
  683. ListView_GetItemCount( hList )
  684. );
  685. }
  686. }
  687. }
  688. //------------------------------------------------------------------------
  689. // link list methods
  690. //------------------------------------------------------------------------
  691. BOOL AddItem( LPTSTR szMachineName , LPTSTR szTimeFormat , LPTSTR szType )
  692. {
  693. ODS( TEXT("LSVIEW : Adding an item\n" ) );
  694. if( g_pHead == NULL )
  695. {
  696. return FALSE;
  697. }
  698. PLIST pNewItem = ( PLIST )new LIST[1];
  699. if( pNewItem == NULL )
  700. {
  701. ODS( TEXT( "LSVIEW AddItem out of memory\n" ) );
  702. return FALSE;
  703. }
  704. pNewItem->pNext = NULL;
  705. if( szMachineName != NULL )
  706. {
  707. pNewItem->pszMachineName = ( LPTSTR )new TCHAR[ lstrlen( szMachineName ) + 1 ];
  708. if( pNewItem->pszMachineName != NULL )
  709. {
  710. lstrcpy( pNewItem->pszMachineName , szMachineName );
  711. }
  712. }
  713. else
  714. {
  715. pNewItem->pszMachineName = NULL;
  716. }
  717. if( szTimeFormat != NULL )
  718. {
  719. pNewItem->pszTimeFormat = ( LPTSTR )new TCHAR[ lstrlen( szTimeFormat ) + 1 ];
  720. if( pNewItem->pszTimeFormat != NULL )
  721. {
  722. lstrcpy( pNewItem->pszTimeFormat , szTimeFormat );
  723. }
  724. }
  725. else
  726. {
  727. pNewItem->pszTimeFormat = NULL;
  728. }
  729. if( szType != NULL )
  730. {
  731. pNewItem->pszType = ( LPTSTR )new TCHAR[ lstrlen( szType ) + 1 ];
  732. if( pNewItem->pszType != NULL )
  733. {
  734. lstrcpy( pNewItem->pszType , szType );
  735. }
  736. }
  737. else
  738. {
  739. pNewItem->pszType = NULL;
  740. }
  741. //=--- find the next available entry
  742. PLIST pTemp = g_pHead;
  743. while( pTemp->pNext != NULL )
  744. {
  745. pTemp = pTemp->pNext;
  746. }
  747. pTemp->pNext = pNewItem;
  748. return TRUE;
  749. }
  750. //------------------------------------------------------------------------
  751. BOOL DeleteList( PLIST pStart )
  752. {
  753. PLIST pPleaseKillMe;
  754. if( pStart == NULL )
  755. {
  756. return TRUE;
  757. }
  758. while( pStart != NULL )
  759. {
  760. pPleaseKillMe = pStart->pNext;
  761. if( pStart->pszMachineName != NULL )
  762. {
  763. delete[] pStart->pszMachineName;
  764. }
  765. if( pStart->pszTimeFormat != NULL )
  766. {
  767. delete[] pStart->pszTimeFormat;
  768. }
  769. if( pStart->pszType != NULL )
  770. {
  771. delete[] pStart->pszType;
  772. }
  773. delete pStart;
  774. pStart = pPleaseKillMe;
  775. }
  776. return TRUE;
  777. }
  778. //------------------------------------------------------------------------
  779. void CreateLogFile( HWND hwnd )
  780. {
  781. // start the save as dialog
  782. OPENFILENAME ofn;
  783. TCHAR szBuffer[ 60 ];
  784. TCHAR szFilter[ 60 ] = { 0 };
  785. TCHAR szFileName[ MAX_PATH ];
  786. TCHAR szExt[ 10 ];
  787. DATAOBJECT dobj;
  788. ZeroMemory( &ofn , sizeof( OPENFILENAME ) );
  789. ZeroMemory( &dobj , sizeof( DATAOBJECT ) );
  790. RetrieveDataObject( &dobj );
  791. if( dobj.bIsChecked )
  792. {
  793. lstrcpy( szFileName , dobj.wchFileName );
  794. }
  795. else
  796. {
  797. szFileName[0] = 0;
  798. }
  799. LoadString( g_hinst ,
  800. IDS_FILTER ,
  801. szFilter ,
  802. SIZEOF( szFilter )
  803. );
  804. LoadString( g_hinst ,
  805. IDS_EXTENSION ,
  806. szExt ,
  807. SIZEOF( szExt )
  808. );
  809. ofn.lStructSize = sizeof( OPENFILENAME );
  810. ofn.hwndOwner = hwnd;
  811. ofn.lpstrFilter = szFilter;
  812. ofn.lpstrFile = szFileName;
  813. ofn.nMaxFile = MAX_PATH;
  814. ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK;
  815. ofn.lpTemplateName = MAKEINTRESOURCE( IDD_CDEXT );
  816. ofn.lpstrDefExt = szExt;
  817. ofn.hInstance = g_hinst;
  818. ofn.FlagsEx = OFN_EX_NOPLACESBAR;
  819. ofn.lpfnHook = OFNHookProc;
  820. // ok let's make them wait
  821. WaitForSingleObject( g_hEvent , INFINITE );
  822. // motion for yellow
  823. LoadString( g_hinst ,
  824. IDS_TRAYFILE ,
  825. szBuffer ,
  826. SIZEOF( szBuffer )
  827. );
  828. Tray_ToYellow( hwnd , szBuffer );
  829. if( GetSaveFileName( &ofn ) )
  830. {
  831. if( g_bDiagnosticLog )
  832. LogDiagnosisFile( szFileName );
  833. else
  834. LogFile( szFileName );
  835. }
  836. else
  837. {
  838. DBGMSG( TEXT( "Last error was 0x%x\n" ) , CommDlgExtendedError( ) );
  839. }
  840. // motion for green
  841. Tray_ToGreen( hwnd );
  842. SetEvent( g_hEvent );
  843. }
  844. //-------------------------------------------------------------------------
  845. UINT_PTR CALLBACK OFNHookProc(
  846. HWND hdlg, // handle to child dialog box window
  847. UINT uiMsg, // message identifier
  848. WPARAM wParam, // message parameter
  849. LPARAM lParam // message parameter
  850. )
  851. {
  852. DATAOBJECT dobj;
  853. TCHAR szDigits[ 16 ];
  854. switch( uiMsg )
  855. {
  856. case WM_INITDIALOG:
  857. {
  858. ODS( TEXT("OFNHookProc WM_INITDIALOG\n" ) );
  859. ZeroMemory( &dobj , sizeof( DATAOBJECT ) );
  860. SendMessage( GetDlgItem( hdlg , IDC_SPIN1 ) , UDM_SETRANGE32 , ( WPARAM ) 1 , ( LPARAM )71582 );
  861. SendMessage( GetDlgItem( hdlg , IDC_SPIN1 ) , UDM_SETPOS32 , 1 , 0 );
  862. RetrieveDataObject( &dobj );
  863. CheckDlgButton( hdlg ,
  864. IDC_CHECK1 ,
  865. dobj.bIsChecked ? BST_CHECKED : BST_UNCHECKED
  866. );
  867. CheckDlgButton( hdlg ,
  868. IDC_CHECK2 ,
  869. dobj.bIsDiagnosisChecked ? BST_CHECKED : BST_UNCHECKED
  870. );
  871. dobj.dwTimeInterval = ( g_dwInterval / 60 ) / 1000 ;
  872. StoreDataObject( &dobj );
  873. if( dobj.dwTimeInterval > 0 )
  874. {
  875. wsprintf( szDigits , TEXT("%d" ), dobj.dwTimeInterval );
  876. SetWindowText( GetDlgItem( hdlg , ID_EDT_NUM ) , szDigits );
  877. }
  878. }
  879. break;
  880. case WM_NOTIFY:
  881. {
  882. ODS( TEXT("OFNHookProc WM_NOTIFY\n" ) );
  883. LPOFNOTIFY pOnotify = ( LPOFNOTIFY )lParam;
  884. if( pOnotify != NULL && pOnotify->hdr.code == CDN_FILEOK )
  885. {
  886. DBGMSG( TEXT("File name to store in registry %s.\n") , pOnotify->lpOFN->lpstrFile );
  887. ZeroMemory( &dobj , sizeof( DATAOBJECT ) );
  888. lstrcpy( dobj.wchFileName , pOnotify->lpOFN->lpstrFile );
  889. GetWindowText( GetDlgItem( hdlg , ID_EDT_NUM ) , szDigits , SIZEOF( szDigits ) );
  890. if( szDigits[0] == 0 )
  891. {
  892. // reset to default elaspe time
  893. dobj.dwTimeInterval = 5;
  894. }
  895. else
  896. {
  897. dobj.dwTimeInterval = _wtoi( szDigits );
  898. }
  899. dobj.bIsChecked = IsDlgButtonChecked( hdlg , IDC_CHECK1 ) == BST_CHECKED;
  900. g_bAutomaticLog = dobj.bIsChecked;
  901. dobj.bIsDiagnosisChecked = IsDlgButtonChecked( hdlg , IDC_CHECK2 ) == BST_CHECKED;
  902. g_bDiagnosticLog = dobj.bIsDiagnosisChecked;
  903. if( dobj.dwTimeInterval < 1 )
  904. {
  905. dobj.dwTimeInterval = 1;
  906. }
  907. if( dobj.dwTimeInterval > kMaxMinutes )
  908. {
  909. dobj.dwTimeInterval = kMaxMinutes;
  910. }
  911. dobj.bNotifyOnce = TRUE;
  912. g_dwInterval = dobj.dwTimeInterval * 60 * 1000;
  913. KillTimer( GetParent( GetParent( hdlg ) ) , kTimerId );
  914. SetTimer( GetParent( GetParent( hdlg ) ) , kTimerId , g_dwInterval , NULL );
  915. StoreDataObject( &dobj );
  916. }
  917. }
  918. break;
  919. }
  920. return 0;
  921. }
  922. //-------------------------------------------------------------------------
  923. BOOL Tray_Init( HWND hwnd , BOOL bNotify )
  924. {
  925. NOTIFYICONDATA nid;
  926. TCHAR szTip[ 60 ];
  927. TCHAR szBubble[ 255 ];
  928. TCHAR szTitle[ 60 ];
  929. ZeroMemory( &nid , sizeof( NOTIFYICONDATA ) );
  930. LoadString( g_hinst ,
  931. IDS_TIP ,
  932. szTip ,
  933. SIZEOF( szTip )
  934. );
  935. if( !bNotify )
  936. {
  937. LoadString( g_hinst ,
  938. IDS_BUBBLE ,
  939. szBubble ,
  940. SIZEOF( szBubble )
  941. );
  942. LoadString( g_hinst ,
  943. IDS_TITLE ,
  944. szTitle ,
  945. SIZEOF( szTitle )
  946. );
  947. nid.uFlags = NIF_TIP | NIF_INFO;
  948. }
  949. nid.cbSize = sizeof( NOTIFYICONDATA );
  950. nid.hWnd = hwnd;
  951. nid.uID = TN_MESSAGE;
  952. nid.uFlags |= NIF_ICON | NIF_MESSAGE;
  953. nid.uCallbackMessage = TN_MESSAGE;
  954. nid.hIcon = LoadIcon( g_hinst , MAKEINTRESOURCE( IDC_ICON_NONE ) );
  955. lstrcpy( nid.szTip , szTip );
  956. lstrcpy( nid.szInfo , szBubble );
  957. lstrcpy( nid.szInfoTitle , szTitle );
  958. nid.dwInfoFlags = NIIF_INFO;
  959. nid.uTimeout = kBubbleTimeout;
  960. return Shell_NotifyIcon( NIM_ADD , &nid );
  961. }
  962. //-------------------------------------------------------------------------
  963. BOOL Tray_ToGreen( HWND hwnd )
  964. {
  965. TCHAR szBuffer[ 260 ];
  966. LoadString( g_hinst ,
  967. IDS_TRAYGREEN ,
  968. szBuffer ,
  969. SIZEOF( szBuffer)
  970. );
  971. return Tray_ToXXX( hwnd , szBuffer , IDC_ICON_GO );
  972. }
  973. //-------------------------------------------------------------------------
  974. BOOL Tray_ToYellow( HWND hwnd , LPTSTR szMsg )
  975. {
  976. return Tray_ToXXX( hwnd , szMsg , IDC_ICON_CAUTION );
  977. }
  978. //-------------------------------------------------------------------------
  979. BOOL Tray_ToRed( HWND hwnd )
  980. {
  981. TCHAR szBuffer[ 260 ];
  982. LoadString( g_hinst ,
  983. IDS_TRAYSTOP ,
  984. szBuffer ,
  985. SIZEOF( szBuffer)
  986. );
  987. return Tray_ToXXX( hwnd , szBuffer , IDC_ICON_STOP );
  988. }
  989. //-------------------------------------------------------------------------
  990. BOOL Tray_Remove( HWND hwnd )
  991. {
  992. NOTIFYICONDATA nid;
  993. ZeroMemory( &nid , sizeof( NOTIFYICONDATA ) );
  994. nid.cbSize = sizeof( NOTIFYICONDATA );
  995. nid.hWnd = hwnd;
  996. nid.uID = TN_MESSAGE;
  997. return Shell_NotifyIcon( NIM_DELETE , &nid );
  998. }
  999. //-------------------------------------------------------------------------
  1000. BOOL Tray_ToXXX( HWND hwnd , LPTSTR szTip , UINT resid )
  1001. {
  1002. NOTIFYICONDATA nid;
  1003. ZeroMemory( &nid , sizeof( NOTIFYICONDATA ) );
  1004. nid.cbSize = sizeof( NOTIFYICONDATA );
  1005. nid.hWnd = hwnd;
  1006. nid.uID = TN_MESSAGE;
  1007. nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
  1008. nid.uCallbackMessage = TN_MESSAGE;
  1009. nid.hIcon = LoadIcon( g_hinst , MAKEINTRESOURCE( resid ) );
  1010. lstrcpy( nid.szTip , szTip );
  1011. return Shell_NotifyIcon( NIM_MODIFY , &nid );
  1012. }
  1013. //-------------------------------------------------------------------------
  1014. BOOL Tray_Notify( HWND hwnd , WPARAM wp , LPARAM lp )
  1015. {
  1016. switch( lp )
  1017. {
  1018. case WM_LBUTTONDBLCLK:
  1019. OpenIcon( hwnd );
  1020. SetForegroundWindow( hwnd );
  1021. break;
  1022. case WM_RBUTTONDOWN:
  1023. {
  1024. HMENU hmenuParent = LoadMenu( g_hinst, MAKEINTRESOURCE( IDR_TRAYMENU ) );
  1025. if( hmenuParent != NULL )
  1026. {
  1027. HMENU hpopup = GetSubMenu( hmenuParent , 0 );
  1028. RemoveMenu( hmenuParent , 0 , MF_BYPOSITION );
  1029. DestroyMenu( hmenuParent );
  1030. // Display the tray icons context menu at
  1031. // the current cursor location
  1032. if( hpopup != NULL )
  1033. {
  1034. POINT pt;
  1035. GetCursorPos( &pt );
  1036. SetForegroundWindow( hwnd );
  1037. TrackPopupMenuEx( hpopup,
  1038. 0,
  1039. pt.x,
  1040. pt.y,
  1041. hwnd,
  1042. NULL);
  1043. DestroyMenu(hpopup);
  1044. }
  1045. }
  1046. }
  1047. break;
  1048. }
  1049. return FALSE;
  1050. }
  1051. //-------------------------------------------------------------------------
  1052. // pObj is a pointer a DATAOBJECT buffer
  1053. //-------------------------------------------------------------------------
  1054. BOOL StoreDataObject( PDATAOBJECT pObj )
  1055. {
  1056. DWORD dwStatus;
  1057. HKEY hKey;
  1058. dwStatus = RegCreateKeyEx( HKEY_CURRENT_USER ,
  1059. szLsViewKey,
  1060. 0,
  1061. NULL,
  1062. 0,
  1063. KEY_WRITE,
  1064. NULL,
  1065. &hKey,
  1066. NULL );
  1067. if( dwStatus != ERROR_SUCCESS )
  1068. {
  1069. // format a message and display an error
  1070. return FALSE;
  1071. }
  1072. dwStatus = RegSetValueEx( hKey,
  1073. TEXT( "DataObject" ),
  1074. 0,
  1075. REG_BINARY,
  1076. ( CONST BYTE * )pObj,
  1077. sizeof( DATAOBJECT ) );
  1078. if( dwStatus != ERROR_SUCCESS )
  1079. {
  1080. RegCloseKey( hKey );
  1081. return FALSE;
  1082. }
  1083. RegCloseKey( hKey );
  1084. return TRUE;
  1085. }
  1086. //-------------------------------------------------------------------------
  1087. // pObj is a pointer to a DATAOBJECT buffer
  1088. //-------------------------------------------------------------------------
  1089. BOOL RetrieveDataObject( PDATAOBJECT pObj )
  1090. {
  1091. DWORD dwStatus;
  1092. DWORD dwSizeOfDO = sizeof( DATAOBJECT );
  1093. HKEY hKey;
  1094. dwStatus = RegOpenKeyEx( HKEY_CURRENT_USER ,
  1095. szLsViewKey,
  1096. 0,
  1097. KEY_READ,
  1098. &hKey );
  1099. if( dwStatus != ERROR_SUCCESS )
  1100. {
  1101. // could obtain information which is ok.
  1102. return FALSE;
  1103. }
  1104. dwStatus = RegQueryValueEx( hKey,
  1105. TEXT( "DataObject" ),
  1106. 0,
  1107. 0,
  1108. ( LPBYTE )pObj,
  1109. &dwSizeOfDO );
  1110. if( dwStatus != ERROR_SUCCESS )
  1111. {
  1112. DBGMSG( TEXT( "LSVIEW:RetrieveDataObject RegOpenKey succeed QueryValueEx failed 0x%x\n" ) , dwStatus );
  1113. RegCloseKey( hKey );
  1114. return FALSE;
  1115. }
  1116. RegCloseKey( hKey );
  1117. return TRUE;
  1118. }
  1119. //-------------------------------------------------------------------------
  1120. BOOL LogFile( LPTSTR szFileName )
  1121. {
  1122. FILE *fp = NULL;
  1123. if( ( fp = _wfopen( szFileName , TEXT( "w" ) ) ) != NULL )
  1124. {
  1125. DBGMSG( TEXT( "File name is %ws\n" ) , szFileName ) ;
  1126. // delimiter not specified use tabs,
  1127. // loop through list and construct a line
  1128. if( g_pHead != NULL )
  1129. {
  1130. PLIST pItem = g_pHead->pNext;
  1131. while( pItem != NULL )
  1132. {
  1133. WCHAR wchBuffer[ 260 ];
  1134. CHAR chBuffer[ 260 ];
  1135. if((sizeof(wchBuffer)/sizeof(wchBuffer[0])) < (wcslen(pItem->pszMachineName) + wcslen(pItem->pszTimeFormat) + wcslen(pItem->pszType) + 1 ))
  1136. {
  1137. fclose( fp );
  1138. return FALSE;
  1139. }
  1140. wsprintf( wchBuffer ,
  1141. TEXT( "%ws\t%ws\t%ws\n" ) ,
  1142. pItem->pszMachineName ,
  1143. pItem->pszTimeFormat ,
  1144. pItem->pszType );
  1145. // DBCS is a hard when streaming; convert this to MBCS
  1146. WideCharToMultiByte( CP_ACP ,
  1147. 0,
  1148. wchBuffer,
  1149. SIZEOF( wchBuffer ),
  1150. chBuffer,
  1151. sizeof( chBuffer ),
  1152. NULL,
  1153. NULL
  1154. );
  1155. fprintf( fp , chBuffer );
  1156. pItem = pItem->pNext;
  1157. }
  1158. }
  1159. fclose( fp );
  1160. }
  1161. return TRUE;
  1162. }