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.

1350 lines
32 KiB

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