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.

696 lines
14 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
  4. //
  5. //
  6. // This workspace contains two projects -
  7. // 1. ProgHelp which implements the Progress Interface
  8. // 2. The Sample application WmdmApp.
  9. //
  10. // ProgHelp.dll needs to be registered first for the SampleApp to run.
  11. // Includes
  12. //
  13. #include "appPCH.h"
  14. #include "appRC.h"
  15. // Constants
  16. //
  17. #define _szWNDCLASS_MAIN "DrmXferAppWnd_Main"
  18. #define _szMUTEX_APP "DrmXferApplication_Mutex"
  19. #define MIN_MAINWND_W 400
  20. #define SHOWBUFFER 10
  21. // Macros
  22. //
  23. // Global variables
  24. //
  25. HINSTANCE g_hInst = NULL;
  26. HWND g_hwndMain = NULL;
  27. CStatus g_cStatus;
  28. CDevices g_cDevices;
  29. CDevFiles g_cDevFiles;
  30. CWMDM g_cWmdm;
  31. BOOL g_bUseOperationInterface = FALSE;
  32. // Local variables
  33. //
  34. static HANDLE _hMutexDrmXfer = NULL;
  35. // Local functions
  36. //
  37. static VOID _CleanUp( void );
  38. static VOID _InitSize( void );
  39. static VOID _OnSize( HWND hwnd, WPARAM wParam, LPARAM lParam );
  40. static VOID _OnMove( HWND hwnd, WPARAM wParam, LPARAM lParam );
  41. static BOOL _InitWindow( void );
  42. static BOOL _RegisterWindowClass( void );
  43. static BOOL _UsePrevInstance( void );
  44. // Local non-static functions
  45. //
  46. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
  47. BOOL CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  48. // Command handlers
  49. //
  50. #define _nNUM_HANDLERS 5
  51. typedef VOID (*HandleFunc) ( WPARAM wParam, LPARAM lParam );
  52. static VOID _OnDeviceReset( WPARAM wParam, LPARAM lParam );
  53. static VOID _OnDeviceClose( WPARAM wParam, LPARAM lParam );
  54. static VOID _OnViewRefresh( WPARAM wParam, LPARAM lParam );
  55. static VOID _OnFileDelete( WPARAM wParam, LPARAM lParam );
  56. static VOID _OnOptionsUseOperationInterface( WPARAM wParam, LPARAM lParam );
  57. struct {
  58. UINT uID;
  59. HandleFunc pfnHandler;
  60. }
  61. _handlers[ _nNUM_HANDLERS ] =
  62. {
  63. { IDM_DEVICE_RESET, _OnDeviceReset },
  64. { IDM_CLOSE, _OnDeviceClose },
  65. { IDM_REFRESH, _OnViewRefresh },
  66. { IDM_DELETE, _OnFileDelete },
  67. { IDM_OPTIONS_USE_OPERATION_INTERFACE, _OnOptionsUseOperationInterface },
  68. };
  69. //
  70. //
  71. int WINAPI WinMain(HINSTANCE hInstance,
  72. HINSTANCE hPrevInstance,
  73. LPSTR lpCmdLine,
  74. int nCmdShow)
  75. {
  76. WPARAM wParam;
  77. g_hInst = hInstance;
  78. InitCommonControls();
  79. if( _UsePrevInstance() )
  80. {
  81. return 0;
  82. }
  83. // Initialize COM
  84. //
  85. ExitOnFail( CoInitialize(NULL) );
  86. // Initialize registry
  87. //
  88. SetRegistryParams( g_hInst, HKEY_LOCAL_MACHINE );
  89. // Initialize the local environment and windows
  90. //
  91. ExitOnFalse( _RegisterWindowClass() );
  92. ExitOnFalse( _InitWindow() );
  93. // Initialize the WMDM
  94. //
  95. ExitOnFail( g_cWmdm.Init());
  96. // Enter message pump until app is closed
  97. //
  98. wParam = DoMsgLoop( TRUE );
  99. // Uninitialize COM
  100. //
  101. CoFreeUnusedLibraries();
  102. CoUninitialize();
  103. return (int)wParam;
  104. lExit:
  105. return 0;
  106. }
  107. LRESULT CALLBACK WndProc_Main(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  108. {
  109. WORD wId = LOWORD( (DWORD)wParam );
  110. WORD wNotifyCode = HIWORD( (DWORD)wParam );
  111. switch( uMsg )
  112. {
  113. case WM_CREATE:
  114. PostMessage( hWnd, WM_DRM_INIT, 0, 0 );
  115. break;
  116. case WM_DRM_INIT:
  117. _OnViewRefresh( 0, 0 );
  118. break;
  119. case WM_DRM_DELETEITEM:
  120. _OnFileDelete( 0, 0 );
  121. break;
  122. case WM_COMMAND:
  123. // Menu item selected
  124. if( BN_CLICKED == wNotifyCode || 0 == wNotifyCode || 1 == wNotifyCode )
  125. {
  126. INT i;
  127. for( i=0; i < _nNUM_HANDLERS; i++ )
  128. {
  129. if( wId == _handlers[i].uID )
  130. {
  131. (*_handlers[i].pfnHandler)( wParam, lParam );
  132. return 0;
  133. }
  134. }
  135. }
  136. break;
  137. case WM_ENDSESSION:
  138. if( (BOOL)wParam )
  139. {
  140. // shutting down
  141. _CleanUp();
  142. }
  143. break;
  144. case WM_SIZE:
  145. _OnSize( hWnd, wParam, lParam );
  146. return 0;
  147. case WM_SYSCOMMAND:
  148. if( SC_MAXIMIZE == wParam )
  149. {
  150. _OnSize( hWnd, wParam, lParam );
  151. return 0;
  152. }
  153. break;
  154. case WM_CLOSE:
  155. _CleanUp();
  156. PostQuitMessage( 0 );
  157. break;
  158. case WM_MOVE:
  159. _OnMove( hWnd, wParam, lParam );
  160. return 0;
  161. case WM_KEYDOWN:
  162. if( wParam == VK_F5 )
  163. {
  164. _OnViewRefresh( 0, 0 );
  165. return 0;
  166. }
  167. break;
  168. case WM_GETMINMAXINFO:
  169. {
  170. LPMINMAXINFO lpmmi = (LPMINMAXINFO) lParam;
  171. lpmmi->ptMinTrackSize.x = MIN_MAINWND_W;
  172. }
  173. return 0;
  174. case WM_INITMENU:
  175. // Enable/disable 'Delete' - command
  176. EnableMenuItem( (HMENU)wParam, IDM_DELETE, MF_BYCOMMAND |
  177. (g_cDevFiles.OkToDelete()) ? MF_ENABLED : MF_GRAYED );
  178. break;
  179. default:
  180. break;
  181. }
  182. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  183. }
  184. VOID _OnViewRefresh( WPARAM wParam, LPARAM lParam )
  185. {
  186. HRESULT hr;
  187. HCURSOR hCursorPrev;
  188. // Show a wait cursor
  189. //
  190. hCursorPrev = SetCursor( LoadCursor(NULL, IDC_WAIT) );
  191. // Remove all current files
  192. //
  193. g_cDevFiles.RemoveAllItems();
  194. // Process messages to allow UI to refresh
  195. //
  196. UiYield();
  197. // Remove all devices
  198. //
  199. g_cDevices.RemoveAllItems();
  200. // Reset the device enumerator
  201. //
  202. hr = g_cWmdm.m_pEnumDevice->Reset();
  203. ExitOnFail( hr );
  204. // Loop through all devices and add them to the list
  205. //
  206. while( TRUE )
  207. {
  208. IWMDMDevice *pWmdmDevice;
  209. CItemData *pItemDevice;
  210. ULONG ulFetched;
  211. hr = g_cWmdm.m_pEnumDevice->Next( 1, &pWmdmDevice, &ulFetched );
  212. if( hr != S_OK )
  213. {
  214. break;
  215. }
  216. if( ulFetched != 1 )
  217. {
  218. ExitOnFail( hr = E_UNEXPECTED );
  219. }
  220. pItemDevice = new CItemData;
  221. if( pItemDevice )
  222. {
  223. hr = pItemDevice->Init( pWmdmDevice );
  224. if( SUCCEEDED(hr) )
  225. {
  226. g_cDevices.AddItem( pItemDevice );
  227. }
  228. else
  229. {
  230. delete pItemDevice;
  231. }
  232. }
  233. pWmdmDevice->Release();
  234. }
  235. // Update the device portion of the status bar
  236. //
  237. g_cDevices.UpdateStatusBar();
  238. // Update the file portion of the status bar
  239. //
  240. g_cDevFiles.UpdateStatusBar();
  241. // Use the default selection
  242. //
  243. g_cDevices.UpdateSelection( NULL, FALSE );
  244. // Return cursor to previous state
  245. //
  246. SetCursor( hCursorPrev );
  247. lExit:
  248. return;
  249. }
  250. VOID _OnDeviceReset( WPARAM wParam, LPARAM lParam )
  251. {
  252. CProgress cProgress;
  253. CItemData *pItemDevice;
  254. HRESULT hr;
  255. HTREEITEM hItem;
  256. // Get the selected device to reset
  257. //
  258. hItem = g_cDevices.GetSelectedItem( (LPARAM *)&pItemDevice );
  259. ExitOnNull( hItem );
  260. ExitOnNull( pItemDevice );
  261. // You can only format devices, not individual folders
  262. //
  263. ExitOnFalse( pItemDevice->m_fIsDevice );
  264. // Create a progress dialog
  265. //
  266. ExitOnFalse( cProgress.Create(g_hwndMain) );
  267. // Set operation progress values
  268. //
  269. cProgress.SetOperation( "Initializing Device..." );
  270. cProgress.SetDetails( pItemDevice->m_szName );
  271. cProgress.SetRange( 0, 100 );
  272. cProgress.SetCount( -1, -1 );
  273. cProgress.SetBytes( -1, -1 );
  274. cProgress.Show( TRUE );
  275. hr = pItemDevice->m_pStorageGlobals->Initialize( WMDM_MODE_BLOCK, NULL );
  276. cProgress.Show( FALSE );
  277. cProgress.Destroy();
  278. lExit:
  279. // Refresh the display
  280. //
  281. g_cDevices.UpdateSelection( NULL, FALSE );
  282. }
  283. VOID _OnFileDelete( WPARAM wParam, LPARAM lParam )
  284. {
  285. CProgress cProgress;
  286. HRESULT hr;
  287. INT i;
  288. INT *pnSelItems = NULL;
  289. INT nNumSel;
  290. // Get the number of selected items.
  291. // Exit if there are no items selected.
  292. //
  293. nNumSel = 0;
  294. g_cDevFiles.GetSelectedItems( pnSelItems, &nNumSel );
  295. ExitOnTrue( 0 == nNumSel );
  296. // Allocate space to hold them the selected items
  297. //
  298. pnSelItems = new INT[ nNumSel ];
  299. ExitOnNull( pnSelItems );
  300. // Get the selected file(s) to delete
  301. //
  302. ExitOnTrue( -1 == g_cDevFiles.GetSelectedItems(pnSelItems, &nNumSel) );
  303. // Create a progress dialog
  304. //
  305. ExitOnFalse( cProgress.Create(g_hwndMain) );
  306. // Set operation progress values
  307. //
  308. cProgress.SetOperation( "Deleting Files..." );
  309. cProgress.SetRange( 0, nNumSel );
  310. cProgress.SetCount( 0, nNumSel );
  311. cProgress.SetBytes( -1, -1 );
  312. for( i=nNumSel-1; i >= 0; i-- )
  313. {
  314. CItemData *pStorage;
  315. // Get the storage object for the current item to delete
  316. //
  317. pStorage = (CItemData *)ListView_GetLParam( g_cDevFiles.GetHwnd_LV(), pnSelItems[i] );
  318. if( NULL != pStorage )
  319. {
  320. IWMDMStorageControl *pStorageControl;
  321. // Set the name of the object and show the progress dialog
  322. //
  323. cProgress.SetDetails( pStorage->m_szName );
  324. cProgress.IncCount();
  325. cProgress.IncPos( 1 );
  326. cProgress.Show( TRUE );
  327. hr = pStorage->m_pStorage->QueryInterface(
  328. IID_IWMDMStorageControl,
  329. reinterpret_cast<void**>(&pStorageControl)
  330. );
  331. if( SUCCEEDED(hr) )
  332. {
  333. hr = pStorageControl->Delete( WMDM_MODE_BLOCK, NULL );
  334. if( SUCCEEDED(hr) )
  335. {
  336. ListView_DeleteItem( g_cDevFiles.GetHwnd_LV(), pnSelItems[i] );
  337. }
  338. pStorageControl->Release();
  339. }
  340. }
  341. }
  342. cProgress.Show( FALSE );
  343. cProgress.Destroy();
  344. lExit:
  345. if( pnSelItems )
  346. {
  347. delete [] pnSelItems;
  348. }
  349. // Refresh the device/devicefiles display
  350. //
  351. g_cDevices.UpdateSelection( NULL, FALSE );
  352. }
  353. VOID _OnDeviceClose( WPARAM wParam, LPARAM lParam )
  354. {
  355. PostMessage( g_hwndMain, WM_CLOSE, (WPARAM)0, (LPARAM)0 );
  356. }
  357. //
  358. VOID _OnOptionsUseOperationInterface( WPARAM wParam, LPARAM lParam )
  359. {
  360. HMENU hMainMenu;
  361. HMENU hOptionsMenu;
  362. // Remember new state
  363. g_bUseOperationInterface = !g_bUseOperationInterface;
  364. // Check uncheck menu
  365. hMainMenu = GetMenu(g_hwndMain);
  366. hOptionsMenu = GetSubMenu( hMainMenu, 1 );
  367. CheckMenuItem( hOptionsMenu, IDM_OPTIONS_USE_OPERATION_INTERFACE,
  368. MF_BYCOMMAND |
  369. (g_bUseOperationInterface ? MF_CHECKED : MF_UNCHECKED));
  370. }
  371. BOOL _InitWindow( void )
  372. {
  373. BOOL fRet = FALSE;
  374. CHAR szApp[MAX_PATH];
  375. LoadString( g_hInst, IDS_APP_TITLE, szApp, sizeof(szApp) );
  376. g_hwndMain = CreateWindowEx(
  377. 0L,
  378. _szWNDCLASS_MAIN,
  379. szApp,
  380. WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | DS_3DLOOK | WS_CLIPCHILDREN,
  381. 0, 0, 0, 0,
  382. NULL, NULL, g_hInst, NULL
  383. );
  384. ExitOnNull( g_hwndMain );
  385. ExitOnFalse( g_cDevices.Create(g_hwndMain) );
  386. ExitOnFalse( g_cDevFiles.Create(g_hwndMain) );
  387. ExitOnFalse( g_cStatus.Create(g_hwndMain) );
  388. _InitSize();
  389. // Show the window
  390. //
  391. ShowWindow( g_hwndMain, SW_SHOW );
  392. fRet = TRUE;
  393. lExit:
  394. return fRet;
  395. }
  396. BOOL _RegisterWindowClass (void)
  397. {
  398. WNDCLASS wc;
  399. wc.style = CS_HREDRAW | CS_VREDRAW;
  400. wc.lpfnWndProc = WndProc_Main;
  401. wc.cbClsExtra = 0;
  402. wc.cbWndExtra = DLGWINDOWEXTRA;
  403. wc.hInstance = g_hInst;
  404. wc.hIcon = LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_ICON) );
  405. wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  406. wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  407. wc.lpszMenuName = MAKEINTRESOURCE( IDR_MENU );
  408. wc.lpszClassName = _szWNDCLASS_MAIN;
  409. return RegisterClass( &wc );
  410. }
  411. VOID _CleanUp( void )
  412. {
  413. if( _hMutexDrmXfer )
  414. {
  415. ReleaseMutex( _hMutexDrmXfer );
  416. CloseHandle( _hMutexDrmXfer );
  417. }
  418. g_cDevices.Destroy();
  419. g_cDevFiles.Destroy();
  420. }
  421. BOOL _UsePrevInstance( void )
  422. {
  423. HWND hwnd;
  424. DWORD dwErr;
  425. // Look for the mutex created by another instance of this app
  426. //
  427. _hMutexDrmXfer = CreateMutex( NULL, TRUE, _szMUTEX_APP );
  428. dwErr = GetLastError();
  429. if( !_hMutexDrmXfer )
  430. {
  431. // The function failed... don't use this instance
  432. //
  433. return TRUE;
  434. }
  435. // If mutex didn't exist, don't use a previous instance
  436. //
  437. if( dwErr != ERROR_ALREADY_EXISTS )
  438. {
  439. return FALSE;
  440. }
  441. hwnd = FindWindow( _szWNDCLASS_MAIN, NULL );
  442. if( !hwnd )
  443. {
  444. // Mutex exists, but the window doesn't?
  445. //
  446. ReleaseMutex( _hMutexDrmXfer );
  447. CloseHandle( _hMutexDrmXfer );
  448. return TRUE;
  449. }
  450. // Show main window that already exists
  451. //
  452. BringWndToTop( hwnd );
  453. return TRUE;
  454. }
  455. INT _GetRegSize( UINT uStrID_RegPath, UINT uStrID_DefVal )
  456. {
  457. DWORD dwRet;
  458. dwRet = GetRegDword_StrTbl(
  459. IDS_REG_PATH_BASE,
  460. uStrID_RegPath,
  461. (DWORD)-1,
  462. FALSE
  463. );
  464. if( (DWORD)-1 == dwRet && -1 != uStrID_DefVal )
  465. {
  466. char szDef[32];
  467. LoadString( g_hInst, uStrID_DefVal, szDef, sizeof(szDef) );
  468. dwRet = (DWORD)atoi( szDef );
  469. }
  470. return (INT) dwRet;
  471. }
  472. VOID _InitSize( void )
  473. {
  474. INT nX, nY, nW, nH;
  475. //
  476. // Get the window position values from the registry
  477. //
  478. nX = _GetRegSize( IDS_REG_KEY_XPOS, (UINT)-1 );
  479. nY = _GetRegSize( IDS_REG_KEY_YPOS, (UINT)-1 );
  480. nW = _GetRegSize( IDS_REG_KEY_WIDTH, IDS_DEF_WIDTH );
  481. nH = _GetRegSize( IDS_REG_KEY_HEIGHT, IDS_DEF_HEIGHT );
  482. // if the position didn't exist in the registry or
  483. // the position is off the screen ( +/- nSHOWBUFFER )
  484. // then center the window, otherwise use the position
  485. if( nX == -1 || nY == -1
  486. || nX + nW < SHOWBUFFER
  487. || nX + SHOWBUFFER > GetSystemMetrics(SM_CXSCREEN)
  488. || nY + nH < SHOWBUFFER
  489. || nY + SHOWBUFFER > GetSystemMetrics(SM_CYSCREEN)
  490. )
  491. {
  492. SetWindowPos( g_hwndMain, NULL, 0, 0, nW, nH, SWP_NOMOVE | SWP_NOZORDER );
  493. CenterWindow( g_hwndMain, NULL );
  494. }
  495. else
  496. {
  497. SetWindowPos( g_hwndMain, NULL, nX, nY, nW, nH, SWP_NOZORDER );
  498. }
  499. }
  500. VOID _OnSize( HWND hwnd, WPARAM wParam, LPARAM lParam )
  501. {
  502. WINDOWPLACEMENT wndpl;
  503. wndpl.length = sizeof( WINDOWPLACEMENT );
  504. if( GetWindowPlacement(hwnd, &wndpl) )
  505. {
  506. DWORD dwW = wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left;
  507. DWORD dwH = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top;
  508. RECT rcMain;
  509. WriteRegDword_StrTbl( IDS_REG_PATH_BASE, IDS_REG_KEY_WIDTH, dwW );
  510. WriteRegDword_StrTbl( IDS_REG_PATH_BASE, IDS_REG_KEY_HEIGHT, dwH );
  511. GetClientRect( hwnd, &rcMain );
  512. // set the position and size of the device window
  513. //
  514. g_cDevices.OnSize( &rcMain );
  515. // set the position and size of the device files window
  516. //
  517. g_cDevFiles.OnSize( &rcMain );
  518. // set the position of the status bar
  519. //
  520. g_cStatus.OnSize( &rcMain );
  521. }
  522. }
  523. VOID _OnMove( HWND hwnd, WPARAM wParam, LPARAM lParam )
  524. {
  525. WINDOWPLACEMENT wndpl;
  526. if( hwnd != g_hwndMain )
  527. {
  528. return;
  529. }
  530. wndpl.length = sizeof(WINDOWPLACEMENT);
  531. if( GetWindowPlacement(hwnd, &wndpl) )
  532. {
  533. WriteRegDword_StrTbl(
  534. IDS_REG_PATH_BASE,
  535. IDS_REG_KEY_XPOS,
  536. wndpl.rcNormalPosition.left
  537. );
  538. WriteRegDword_StrTbl(
  539. IDS_REG_PATH_BASE,
  540. IDS_REG_KEY_YPOS,
  541. wndpl.rcNormalPosition.top
  542. );
  543. }
  544. }