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.

1129 lines
36 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 1999
  4. Module Name:
  5. LocalFileLoggingPage2.cpp
  6. Abstract:
  7. Implementation file for the CLocalFileLoggingPage2 class.
  8. We implement the class needed to handle the second property page
  9. for the LocalFileLogging node.
  10. Author:
  11. Michael A. Maguire 12/15/97
  12. Revision History:
  13. mmaguire 12/15/97 - created
  14. --*/
  15. //////////////////////////////////////////////////////////////////////////////
  16. //////////////////////////////////////////////////////////////////////////////
  17. // BEGIN INCLUDES
  18. //
  19. // standard includes:
  20. //
  21. #include "Precompiled.h"
  22. //
  23. // where we can find declaration for main class in this file:
  24. //
  25. #include "LocalFileLoggingPage2.h"
  26. #include "ChangeNotification.h"
  27. //
  28. //
  29. // where we can find declarations needed in this file:
  30. //
  31. #include <SHLOBJ.H>
  32. #include "LocalFileLoggingNode.h"
  33. #include "LoggingMethodsNode.h"
  34. #include "LogMacNd.h"
  35. //
  36. // END INCLUDES
  37. //////////////////////////////////////////////////////////////////////////////
  38. #define LOG_FILE_FORMAT__IAS1 0
  39. #define LOG_FILE_FORMAT__ODBC 0xFFFF
  40. #define LOG_SIZE_LIMIT 100000
  41. #define LOG_SIZE_LIMIT_DIGITS 6 // log(100000)
  42. //////////////////////////////////////////////////////////////////////////////
  43. /*++
  44. CLocalFileLoggingPage2::CLocalFileLoggingPage2
  45. Constructor
  46. --*/
  47. //////////////////////////////////////////////////////////////////////////////
  48. CLocalFileLoggingPage2::CLocalFileLoggingPage2( LONG_PTR hNotificationHandle, CLocalFileLoggingNode *pLocalFileLoggingNode, TCHAR* pTitle, BOOL bOwnsNotificationHandle )
  49. : CIASPropertyPage<CLocalFileLoggingPage2> ( hNotificationHandle, pTitle, bOwnsNotificationHandle )
  50. {
  51. ATLTRACE(_T("# +++ CLocalFileLoggingPage2::CLocalFileLoggingPage2\n"));
  52. _ASSERTE( pLocalFileLoggingNode != NULL );
  53. // Add the help button to the page
  54. // m_psp.dwFlags |= PSP_HASHELP;
  55. // Initialize the pointer to the stream into which the Sdo pointer will be marshalled.
  56. m_pStreamSdoAccountingMarshal = NULL;
  57. // Initialize the pointer to the stream into which the Sdo pointer will be marshalled.
  58. m_pStreamSdoServiceControlMarshal = NULL;
  59. // We immediately save off a parent to the client node.
  60. // We will use only the SDO, and notify the parent of the client object
  61. // we are modifying that it (and its children) may need to refresh
  62. // themselves with new data from the SDO's.
  63. m_pParentOfNodeBeingModified = pLocalFileLoggingNode->m_pParentNode;
  64. m_pNodeBeingModified = pLocalFileLoggingNode;
  65. }
  66. //////////////////////////////////////////////////////////////////////////////
  67. /*++
  68. CLocalFileLoggingPage2::~CLocalFileLoggingPage2
  69. Destructor
  70. --*/
  71. //////////////////////////////////////////////////////////////////////////////
  72. CLocalFileLoggingPage2::~CLocalFileLoggingPage2( void )
  73. {
  74. ATLTRACE(_T("# --- CLocalFileLoggingPage2::~CLocalFileLoggingPage2\n"));
  75. // Release this stream pointer if this hasn't already been done.
  76. if( m_pStreamSdoAccountingMarshal != NULL )
  77. {
  78. m_pStreamSdoAccountingMarshal->Release();
  79. };
  80. if( m_pStreamSdoServiceControlMarshal != NULL )
  81. {
  82. m_pStreamSdoServiceControlMarshal->Release();
  83. };
  84. }
  85. //////////////////////////////////////////////////////////////////////////////
  86. /*++
  87. CLocalFileLoggingPage2::OnInitDialog
  88. --*/
  89. //////////////////////////////////////////////////////////////////////////////
  90. LRESULT CLocalFileLoggingPage2::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  91. {
  92. ATLTRACE(_T("# CLocalFileLoggingPage2::OnInitDialog\n"));
  93. // Check for preconditions:
  94. _ASSERTE( m_pStreamSdoAccountingMarshal != NULL );
  95. _ASSERT( m_pSynchronizer != NULL );
  96. // Since we've been examined, we must add to the ref count of pages who need to
  97. // give their approval before they can be allowed to commit changes.
  98. m_pSynchronizer->RaiseCount();
  99. HRESULT hr;
  100. CComBSTR bstrTemp;
  101. BOOL bTemp;
  102. LONG lTemp;
  103. // Unmarshall an ISdo interface pointer.
  104. // The code setting up this page should make sure that it has
  105. // marshalled the Sdo interface pointer into m_pStreamSdoAccountingMarshal.
  106. hr = CoGetInterfaceAndReleaseStream(
  107. m_pStreamSdoAccountingMarshal //Pointer to the stream from which the object is to be marshaled
  108. , IID_ISdo //Reference to the identifier of the interface
  109. , (LPVOID *) &m_spSdoAccounting //Address of output variable that receives the interface pointer requested in riid
  110. );
  111. // CoGetInterfaceAndReleaseStream releases this pointer even if it fails.
  112. // We set it to NULL so that our destructor doesn't try to release this again.
  113. m_pStreamSdoAccountingMarshal = NULL;
  114. if( FAILED( hr) || m_spSdoAccounting == NULL )
  115. {
  116. ShowErrorDialog( m_hWnd, IDS_ERROR__NO_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE );
  117. return 0;
  118. }
  119. // Unmarshall an ISdo interface pointer.
  120. // The code setting up this page should make sure that it has
  121. // marshalled the Sdo interface pointer into m_pStreamSdoServiceControlMarshal.
  122. hr = CoGetInterfaceAndReleaseStream(
  123. m_pStreamSdoServiceControlMarshal //Pointer to the stream from which the object is to be marshaled
  124. , IID_ISdoServiceControl //Reference to the identifier of the interface
  125. , (LPVOID *) &m_spSdoServiceControl //Address of output variable that receives the interface pointer requested in riid
  126. );
  127. // CoGetInterfaceAndReleaseStream releases this pointer even if it fails.
  128. // We set it to NULL so that our destructor doesn't try to release this again.
  129. m_pStreamSdoServiceControlMarshal = NULL;
  130. if( FAILED( hr) || m_spSdoServiceControl == NULL )
  131. {
  132. ShowErrorDialog( m_hWnd, IDS_ERROR__NO_SDO, NULL, hr, IDS_ERROR__LOGGING_TITLE );
  133. return 0;
  134. }
  135. // Initialize the data on the property page.
  136. lTemp = 0;
  137. hr = GetSdoI4( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_OPEN_NEW_FREQUENCY, &lTemp, IDS_ERROR__LOCAL_FILE_LOGGING_READING_NEW_LOG_FREQUENCY, m_hWnd, NULL );
  138. if( SUCCEEDED( hr ) )
  139. {
  140. m_fDirtyFrequency = FALSE;
  141. }
  142. else
  143. {
  144. if( OLE_E_BLANK == hr )
  145. {
  146. m_fDirtyFrequency = TRUE;
  147. SetModified( TRUE );
  148. }
  149. }
  150. NEW_LOG_FILE_FREQUENCY nlffFrequency = (NEW_LOG_FILE_FREQUENCY) lTemp;
  151. switch( nlffFrequency )
  152. {
  153. case IAS_LOGGING_DAILY:
  154. ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__DAILY ), BM_SETCHECK, 1, 0 );
  155. break;
  156. case IAS_LOGGING_WEEKLY:
  157. ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WEEKLY ), BM_SETCHECK, 1, 0 );
  158. break;
  159. case IAS_LOGGING_MONTHLY:
  160. ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__MONTHLY ), BM_SETCHECK, 1, 0 );
  161. break;
  162. case IAS_LOGGING_WHEN_FILE_SIZE_REACHES:
  163. ::SendMessage( GetDlgItem(IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES ), BM_SETCHECK, 1, 0 );
  164. break;
  165. case IAS_LOGGING_UNLIMITED_SIZE:
  166. ::SendMessage( GetDlgItem(IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__UNLIMITED ), BM_SETCHECK, 1, 0 );
  167. break;
  168. default:
  169. // Invalid logging frequency.
  170. _ASSERTE( FALSE );
  171. break;
  172. }
  173. ::SendMessage( GetDlgItem(IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE ), EM_LIMITTEXT, LOG_SIZE_LIMIT_DIGITS, 0 );
  174. hr = GetSdoI4( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_OPEN_NEW_SIZE, &lTemp, IDS_ERROR__LOCAL_FILE_LOGGING_READING_WHEN_LOG_FILE_SIZE, m_hWnd, NULL );
  175. if( SUCCEEDED( hr ) )
  176. {
  177. TCHAR szNumberAsText[IAS_MAX_STRING];
  178. _ltot( lTemp, szNumberAsText, 10 /* Base */ );
  179. SetDlgItemText(IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE, szNumberAsText );
  180. m_fDirtyLogFileSize = FALSE;
  181. }
  182. else
  183. {
  184. if( OLE_E_BLANK == hr )
  185. {
  186. SetDlgItemText(IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE, _T("") );
  187. m_fDirtyLogFileSize = TRUE;
  188. SetModified( TRUE );
  189. }
  190. }
  191. hr = GetSdoBSTR( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_FILE_DIRECTORY, &bstrTemp, IDS_ERROR__LOCAL_FILE_LOGGING_READING_LOG_FILE_DIRECTORY, m_hWnd, NULL );
  192. if( SUCCEEDED( hr ) )
  193. {
  194. SetDlgItemText( IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_DIRECTORY, bstrTemp );
  195. m_fDirtyLogFileDirectory = FALSE;
  196. }
  197. else
  198. {
  199. if( OLE_E_BLANK == hr )
  200. {
  201. SetDlgItemText( IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_DIRECTORY, _T("") );
  202. m_fDirtyLogFileDirectory = TRUE;
  203. SetModified( TRUE );
  204. }
  205. }
  206. bstrTemp.Empty();
  207. hr = GetSdoI4( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_IAS1_FORMAT, &lTemp, IDS_ERROR__LOCAL_FILE_LOGGING_READING_LOG_FILE_FORMAT, m_hWnd, NULL );
  208. if( SUCCEEDED( hr ) )
  209. {
  210. switch( lTemp )
  211. {
  212. case LOG_FILE_FORMAT__IAS1:
  213. // W3C format (IAS 1.0)
  214. SendDlgItemMessage( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_IAS1, BM_SETCHECK, TRUE, 0);
  215. SendDlgItemMessage( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_ODBC, BM_SETCHECK, FALSE, 0);
  216. break;
  217. case LOG_FILE_FORMAT__ODBC:
  218. // ODBC format
  219. SendDlgItemMessage( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_ODBC, BM_SETCHECK, TRUE, 0);
  220. SendDlgItemMessage( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_IAS1, BM_SETCHECK, FALSE, 0);
  221. break;
  222. default:
  223. // Unknown log file format.
  224. _ASSERTE( FALSE );
  225. }
  226. m_fDirtyLogInV1Format = FALSE;
  227. }
  228. else
  229. {
  230. if( OLE_E_BLANK == hr )
  231. {
  232. SendDlgItemMessage( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_ODBC, BM_SETCHECK, TRUE, 0);
  233. SendDlgItemMessage( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_IAS1, BM_SETCHECK, FALSE, 0);
  234. m_fDirtyLogInV1Format = TRUE;
  235. SetModified( TRUE );
  236. }
  237. }
  238. VARIANT deleteIfFull;
  239. VariantInit(&deleteIfFull);
  240. hr = m_spSdoAccounting->GetProperty(
  241. PROPERTY_ACCOUNTING_LOG_DELETE_IF_FULL,
  242. &deleteIfFull
  243. );
  244. if (SUCCEEDED(hr))
  245. {
  246. CheckDlgButton(
  247. IDC_CHECK_DELETE_IF_FULL,
  248. (V_BOOL(&deleteIfFull) ? BST_CHECKED : BST_UNCHECKED)
  249. );
  250. VariantClear(&deleteIfFull);
  251. }
  252. else if (hr == DISP_E_MEMBERNOTFOUND)
  253. {
  254. // Property doesn't exist so hide the control.
  255. HWND checkBox = GetDlgItem(IDC_CHECK_DELETE_IF_FULL);
  256. DWORD oldStyle = ::GetWindowLong(checkBox, GWL_STYLE);
  257. DWORD newStyle = (oldStyle & ~WS_VISIBLE);
  258. ::SetWindowLong(checkBox, GWL_STYLE, newStyle);
  259. }
  260. else
  261. {
  262. ShowErrorDialog(m_hWnd, USE_DEFAULT);
  263. }
  264. m_fDirtyDeleteIfFull = FALSE;
  265. // SetAutomaticallyOpenNewLogDependencies();
  266. SetLogFileFrequencyDependencies();
  267. // Check to see whether we are local or remote, and disable Browse
  268. // button if we are remote.
  269. // We need access here to some server-global data.
  270. _ASSERTE( m_pParentOfNodeBeingModified != NULL );
  271. CLoggingMachineNode * pServerNode = ((CLoggingMethodsNode *) m_pParentOfNodeBeingModified)->GetServerRoot();
  272. _ASSERTE( pServerNode != NULL );
  273. if( pServerNode->m_bConfigureLocal )
  274. {
  275. // We are local.
  276. ::EnableWindow( GetDlgItem( IDC_BUTTON_LOCAL_FILE_LOGGING_PAGE2__BROWSE ), TRUE );
  277. }
  278. else
  279. {
  280. // We are remote
  281. ::EnableWindow( GetDlgItem( IDC_BUTTON_LOCAL_FILE_LOGGING_PAGE2__BROWSE ), FALSE );
  282. }
  283. return TRUE; // ISSUE: what do we need to be returning here?
  284. }
  285. //////////////////////////////////////////////////////////////////////////////
  286. /*++
  287. CLocalFileLoggingPage2::OnChange
  288. Called when the WM_COMMAND message is sent to our page with any of the
  289. BN_CLICKED, EN_CHANGE or CBN_SELCHANGE notifications.
  290. This is our chance to check to see what the user has touched, set the
  291. dirty bits for these items so that only they will be saved,
  292. and enable the Apply button.
  293. --*/
  294. //////////////////////////////////////////////////////////////////////////////
  295. LRESULT CLocalFileLoggingPage2::OnChange(
  296. UINT uMsg
  297. , WPARAM wParam
  298. , HWND hwnd
  299. , BOOL& bHandled
  300. )
  301. {
  302. ATLTRACE(_T("# CLocalFileLoggingPage2::OnChange\n"));
  303. // Check for preconditions:
  304. // None.
  305. // We don't want to prevent anyone else down the chain from receiving a message.
  306. bHandled = FALSE;
  307. // Figure out which item has changed and set the dirty bit for that item.
  308. int iItemID = (int) LOWORD(wParam);
  309. switch( iItemID )
  310. {
  311. // case IDC_CHECK_LOCAL_FILE_LOGGING_PAGE2__AUTOMATICALLY_OPEN_NEW_LOG:
  312. // m_fDirtyAutomaticallyOpenNewLog = TRUE;
  313. // break;
  314. case IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__DAILY:
  315. case IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WEEKLY:
  316. case IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__MONTHLY:
  317. case IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES:
  318. case IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__UNLIMITED:
  319. m_fDirtyFrequency = TRUE;
  320. break;
  321. case IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE:
  322. m_fDirtyLogFileSize = TRUE;
  323. break;
  324. case IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_DIRECTORY:
  325. m_fDirtyLogFileDirectory = TRUE;
  326. break;
  327. case IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_ODBC:
  328. case IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_IAS1:
  329. m_fDirtyLogInV1Format = TRUE;
  330. break;
  331. case IDC_CHECK_DELETE_IF_FULL:
  332. {
  333. m_fDirtyDeleteIfFull = TRUE;
  334. break;
  335. }
  336. default:
  337. return TRUE;
  338. break;
  339. }
  340. // We should only get here if the item that changed was
  341. // one of the ones we were checking for.
  342. // This enables the Apply button.
  343. SetModified( TRUE );
  344. return TRUE; // ISSUE: what do we need to be returning here?
  345. }
  346. //////////////////////////////////////////////////////////////////////////////
  347. /*++
  348. CLocalFileLoggingPage2::BrowseCallbackProc
  349. Needed so that we can set the directory which the Browse for Directory dialog displays.
  350. --*/
  351. //////////////////////////////////////////////////////////////////////////////
  352. int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData)
  353. {
  354. switch(uMsg)
  355. {
  356. case BFFM_INITIALIZED:
  357. // pData contains the data we passed in as BROWSEINFO.lParam
  358. // It should a string form of the directory we want the browser to show initially.
  359. if( NULL != pData )
  360. {
  361. // WParam is TRUE since you are passing a path.
  362. // It would be FALSE if you were passing a pidl.
  363. SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)pData);
  364. }
  365. break;
  366. default:
  367. break;
  368. }
  369. return 0;
  370. }
  371. //////////////////////////////////////////////////////////////////////////////
  372. /*++
  373. CLocalFileLoggingPage2::OnBrowse
  374. Action to be taken when the user clicks on the browse button to choose
  375. a directory where log files should be saved.
  376. --*/
  377. //////////////////////////////////////////////////////////////////////////////
  378. LRESULT CLocalFileLoggingPage2::OnBrowse(
  379. UINT uMsg
  380. , WPARAM wParam
  381. , HWND hwnd
  382. , BOOL& bHandled
  383. )
  384. {
  385. ATLTRACE(_T("# CLocalFileLoggingPage2::OnBrowse\n"));
  386. #ifdef USE_GETSAVEFILENAME
  387. OPENFILENAME ofnInfo;
  388. TCHAR szFileName[MAX_PATH + 1]; // buffer must be one TCHAR longer than we say it is later -- see KB Q137194
  389. TCHAR szDialogTitle[IAS_MAX_STRING];
  390. // Initialize the data structure we will pass to GetSaveFileName.
  391. memset(&ofnInfo, 0, sizeof(OPENFILENAME));
  392. // Put a NULL in the first character of szFileName to indicate that
  393. // no initialization is necessary.
  394. szFileName[0] = NULL;
  395. // Set the dialog title.
  396. int nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_BROWSE_DIALOG__TITLE, szDialogTitle, IAS_MAX_STRING );
  397. _ASSERT( nLoadStringResult > 0 );
  398. ofnInfo.lStructSize = sizeof(OPENFILENAME);
  399. ofnInfo.hwndOwner = hwnd;
  400. ofnInfo.lpstrFile = szFileName;
  401. ofnInfo.nMaxFile = MAX_PATH;
  402. ofnInfo.lpstrTitle = szDialogTitle;
  403. if( 0 != GetSaveFileName( &ofnInfo ) )
  404. {
  405. // The user hit OK. We should save the chosen directory in the text box.
  406. CComBSTR bstrText = ofnInfo.lpstrFile;
  407. SetDlgItemText(IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_DIRECTORY, bstrText );
  408. }
  409. else
  410. {
  411. // An error occured or the user hit cancel -- find out which.
  412. DWORD dwError = CommDlgExtendedError();
  413. if( 0 == dwError )
  414. {
  415. // The user simply cancelled or closed the dialog box -- no error occured.
  416. }
  417. else
  418. {
  419. // Some error occurred.
  420. // ISSUE: We should be giving more detailed error info here.
  421. ShowErrorDialog( m_hWnd, USE_DEFAULT, NULL, 0, IDS_ERROR__LOGGING_TITLE);
  422. }
  423. }
  424. #else // DON'T USE_GETSAVEFILENAME
  425. BROWSEINFO biInfo;
  426. TCHAR szFileName[MAX_PATH + 1];
  427. TCHAR szDialogTitle[IAS_MAX_STRING];
  428. // Initialize the data structure we will pass to GetSaveFileName.
  429. memset(&biInfo, 0, sizeof(BROWSEINFO));
  430. // Put a NULL in the first character of szFileName to indicate that
  431. // no initialization is necessary.
  432. szFileName[0] = NULL;
  433. // Set the dialog title.
  434. int nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_BROWSE_DIALOG__TITLE, szDialogTitle, IAS_MAX_STRING );
  435. _ASSERT( nLoadStringResult > 0 );
  436. CComBSTR bstrText;
  437. GetDlgItemText(IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_DIRECTORY,(BSTR &) bstrText );
  438. biInfo.hwndOwner = hwnd;
  439. biInfo.pszDisplayName = szFileName;
  440. biInfo.lpszTitle = szDialogTitle;
  441. biInfo.lpfn = BrowseCallbackProc;
  442. biInfo.lParam = (LPARAM) bstrText.m_str;
  443. LPITEMIDLIST lpItemIDList;
  444. lpItemIDList = SHBrowseForFolder( & biInfo );
  445. if( lpItemIDList != NULL )
  446. {
  447. // The user hit OK. We should save the chosen directory in the text box.
  448. // ISSUE: Need to release the lpItemIDLust structure allocated by the call
  449. // using the shell's task allocator (how???)
  450. // Convert the ItemIDList to a path.
  451. // We clobber the old szFileName here because we don't care about it. (It didn't have the full path.)
  452. BOOL bSuccess = SHGetPathFromIDList( lpItemIDList, szFileName );
  453. if( bSuccess )
  454. {
  455. CComBSTR bstrText = szFileName;
  456. SetDlgItemText(IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_DIRECTORY, bstrText );
  457. }
  458. else
  459. {
  460. // Handle error
  461. ShowErrorDialog( m_hWnd, IDS_ERROR__NOT_A_VALID_DIRECTORY, NULL, 0 , IDS_ERROR__LOGGING_TITLE );
  462. }
  463. }
  464. else
  465. {
  466. // An error occured or the user hit cancel -- find out which.
  467. // SHBrowseInfo seems to have no error checking capabilities.
  468. // The docs say that if it succeeded, it returns non-NULL, and
  469. // if the user chooses Cancel, it returns NULL.
  470. // I tried GetLastError to make sure that there was no error,
  471. // but it gives back 0x00000006 "Invalid handle" even if I
  472. // do SetLastError(0) before I make any calls.
  473. // So it seems that we have no choice but to assume that
  474. // if we get here, there was no error,
  475. // it was simply that the user chose Cancel.
  476. }
  477. #endif // USE_GETSAVEFILENAME
  478. return TRUE; // ISSUE: what do we need to be returning here?
  479. }
  480. //////////////////////////////////////////////////////////////////////////////
  481. /*++
  482. CLocalFileLoggingPage2::OnApply
  483. Return values:
  484. TRUE if the page can be destroyed,
  485. FALSE if the page should not be destroyed (i.e. there was invalid data)
  486. Remarks:
  487. OnApply gets called for each page in on a property sheet if that
  488. page has been visited, regardless of whether any values were changed.
  489. If you never switch to a tab, then its OnApply method will never get called.
  490. --*/
  491. //////////////////////////////////////////////////////////////////////////////
  492. BOOL CLocalFileLoggingPage2::OnApply()
  493. {
  494. ATLTRACE(_T("# CLocalFileLoggingPage2::OnApply\n"));
  495. // Check for preconditions:
  496. _ASSERT( m_pSynchronizer != NULL );
  497. if( m_spSdoAccounting == NULL )
  498. {
  499. ShowErrorDialog( m_hWnd, IDS_ERROR__NO_SDO, NULL, 0, IDS_ERROR__LOGGING_TITLE );
  500. return FALSE;
  501. }
  502. CComBSTR bstrNumberAsText;
  503. BOOL bResult;
  504. HRESULT hr;
  505. BOOL bTemp;
  506. LONG lTemp;
  507. CComBSTR bstrTemp;
  508. if( m_fDirtyFrequency )
  509. {
  510. NEW_LOG_FILE_FREQUENCY nlffFrequency = IAS_LOGGING_MONTHLY;
  511. if( ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__DAILY ), BM_GETCHECK, 0, 0 ) )
  512. nlffFrequency = IAS_LOGGING_DAILY;
  513. else if( ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WEEKLY ), BM_GETCHECK, 0, 0 ) )
  514. nlffFrequency = IAS_LOGGING_WEEKLY;
  515. else if( ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__MONTHLY ), BM_GETCHECK, 0, 0 ) )
  516. nlffFrequency = IAS_LOGGING_MONTHLY;
  517. else if( ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__UNLIMITED ), BM_GETCHECK, 0, 0 ) )
  518. nlffFrequency = IAS_LOGGING_UNLIMITED_SIZE;
  519. else
  520. nlffFrequency = IAS_LOGGING_WHEN_FILE_SIZE_REACHES;
  521. hr = PutSdoI4( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_OPEN_NEW_FREQUENCY, nlffFrequency, IDS_ERROR__LOCAL_FILE_LOGGING_WRITING_NEW_LOG_FREQUENCY, m_hWnd, NULL );
  522. if( FAILED( hr ) )
  523. {
  524. // Reset the ref count so all pages know that we need to play the game again.
  525. m_pSynchronizer->ResetCountToHighest();
  526. // This uses the resource ID of this page to make this page the current page.
  527. PropSheet_SetCurSelByID( GetParent(), IDD );
  528. return FALSE;
  529. }
  530. else
  531. {
  532. // We succeeded.
  533. // Turn off the dirty bit.
  534. m_fDirtyFrequency = FALSE;
  535. }
  536. }
  537. if( m_fDirtyLogFileSize )
  538. {
  539. // When a user enters some (potentially invalid) data, but
  540. // then disables the option using that data, we don't try to save this data.
  541. int iChecked = ::SendMessage( GetDlgItem(IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES), BM_GETCHECK, 0, 0 );
  542. int iEnabled = ::IsWindowEnabled( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES ) );
  543. if( iChecked && iEnabled )
  544. {
  545. bResult = GetDlgItemText( IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE, (BSTR &) bstrNumberAsText );
  546. if( ! bResult )
  547. {
  548. // We couldn't retrieve a BSTR, in other words the field was blank.
  549. // This is an error.
  550. ShowErrorDialog( m_hWnd, IDS_ERROR__LOCAL_FILE_LOGGING_WRITING_WHEN_LOG_FILE_SIZE_NOT_ZERO, NULL, 0, IDS_ERROR__LOGGING_TITLE );
  551. // Reset the ref count so all pages know that we need to play the game again.
  552. m_pSynchronizer->ResetCountToHighest();
  553. // This uses the resource ID of this page to make this page the current page.
  554. PropSheet_SetCurSelByID( GetParent(), IDD );
  555. return FALSE;
  556. }
  557. lTemp = _ttol( bstrNumberAsText );
  558. if( lTemp <= 0 || lTemp > LOG_SIZE_LIMIT)
  559. {
  560. // If result here was zero, this indicates an error.
  561. ShowErrorDialog( m_hWnd, IDS_ERROR__LOCAL_FILE_LOGGING_WRITING_WHEN_LOG_FILE_SIZE_NOT_ZERO, NULL, 0, IDS_ERROR__LOGGING_TITLE );
  562. // Reset the ref count so all pages know that we need to play the game again.
  563. m_pSynchronizer->ResetCountToHighest();
  564. // This uses the resource ID of this page to make this page the current page.
  565. PropSheet_SetCurSelByID( GetParent(), IDD );
  566. return FALSE;
  567. }
  568. bstrNumberAsText.Empty();
  569. hr = PutSdoI4( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_OPEN_NEW_SIZE, lTemp, IDS_ERROR__LOCAL_FILE_LOGGING_WRITING_WHEN_LOG_FILE_SIZE, m_hWnd, NULL );
  570. if( FAILED( hr ) )
  571. {
  572. // Reset the ref count so all pages know that we need to play the game again.
  573. m_pSynchronizer->ResetCountToHighest();
  574. // This uses the resource ID of this page to make this page the current page.
  575. PropSheet_SetCurSelByID( GetParent(), IDD );
  576. return FALSE;
  577. }
  578. else
  579. {
  580. // We succeeded.
  581. // Turn off the dirty bit.
  582. m_fDirtyLogFileSize = FALSE;
  583. }
  584. }
  585. }
  586. if( m_fDirtyLogFileDirectory )
  587. {
  588. bResult = GetDlgItemText( IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_DIRECTORY, (BSTR &) bstrTemp );
  589. if( ! bResult )
  590. {
  591. // We couldn't retrieve a BSTR, so we need to initialize this variant to a null BSTR.
  592. bstrTemp = _T("");
  593. }
  594. hr = PutSdoBSTR( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_FILE_DIRECTORY, &bstrTemp, IDS_ERROR__LOCAL_FILE_LOGGING_WRITING_LOG_FILE_DIRECTORY, m_hWnd, NULL );
  595. if( FAILED( hr ) )
  596. {
  597. // Reset the ref count so all pages know that we need to play the game again.
  598. m_pSynchronizer->ResetCountToHighest();
  599. // This uses the resource ID of this page to make this page the current page.
  600. PropSheet_SetCurSelByID( GetParent(), IDD );
  601. return FALSE;
  602. }
  603. else
  604. {
  605. // We succeeded.
  606. // Turn off the dirty bit.
  607. m_fDirtyLogFileDirectory = FALSE;
  608. }
  609. bstrTemp.Empty();
  610. }
  611. if( m_fDirtyLogInV1Format )
  612. {
  613. if( SendDlgItemMessage( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__FORMAT_IAS1, BM_GETCHECK, 0, 0) )
  614. {
  615. lTemp = LOG_FILE_FORMAT__IAS1;
  616. }
  617. else
  618. {
  619. lTemp = LOG_FILE_FORMAT__ODBC;
  620. }
  621. hr = PutSdoI4( m_spSdoAccounting, PROPERTY_ACCOUNTING_LOG_IAS1_FORMAT, lTemp, IDS_ERROR__LOCAL_FILE_LOGGING_WRITING_LOG_FILE_FORMAT, m_hWnd, NULL );
  622. if( FAILED( hr ) )
  623. {
  624. // Reset the ref count so all pages know that we need to play the game again.
  625. m_pSynchronizer->ResetCountToHighest();
  626. // This uses the resource ID of this page to make this page the current page.
  627. PropSheet_SetCurSelByID( GetParent(), IDD );
  628. return FALSE;
  629. }
  630. else
  631. {
  632. // We succeeded.
  633. // Turn off the dirty bit.
  634. m_fDirtyLogInV1Format = FALSE;
  635. }
  636. }
  637. if (m_fDirtyDeleteIfFull)
  638. {
  639. BOOL deleteIfFull = SendDlgItemMessage(
  640. IDC_CHECK_DELETE_IF_FULL,
  641. BM_GETCHECK,
  642. 0,
  643. 0
  644. );
  645. hr = PutSdoBOOL(
  646. m_spSdoAccounting,
  647. PROPERTY_ACCOUNTING_LOG_DELETE_IF_FULL,
  648. deleteIfFull,
  649. USE_DEFAULT,
  650. m_hWnd,
  651. 0
  652. );
  653. if (SUCCEEDED(hr))
  654. {
  655. m_fDirtyDeleteIfFull = TRUE;
  656. }
  657. else
  658. {
  659. m_pSynchronizer->ResetCountToHighest();
  660. PropSheet_SetCurSelByID( GetParent(), IDD);
  661. return FALSE;
  662. }
  663. }
  664. // If we made it to here, try to apply the changes.
  665. // Check to see if there are other pages which have not yet validated their data.
  666. LONG lRefCount = m_pSynchronizer->LowerCount();
  667. if( lRefCount <= 0 )
  668. {
  669. // There is nobody else left, so now we can commit the data.
  670. hr = m_spSdoAccounting->Apply();
  671. if( FAILED( hr ) )
  672. {
  673. if(hr == DB_E_NOTABLE) // assume, the RPC connection has problem
  674. ShowErrorDialog( m_hWnd, IDS_ERROR__NOTABLE_TO_WRITE_SDO, NULL, 0, IDS_ERROR__LOGGING_TITLE );
  675. else
  676. {
  677. // m_spSdoAccounting->LastError( &bstrError );
  678. // ShowErrorDialog( m_hWnd, IDS_ERROR__CANT_WRITE_DATA_TO_SDO, bstrError );
  679. ShowErrorDialog( m_hWnd, IDS_ERROR__CANT_WRITE_DATA_TO_SDO, NULL, 0, IDS_ERROR__LOGGING_TITLE );
  680. }
  681. // Reset the ref count so all pages know that we need to play the game again.
  682. m_pSynchronizer->ResetCountToHighest();
  683. // This uses the resource ID of this page to make this page the current page.
  684. PropSheet_SetCurSelByID( GetParent(), IDD );
  685. return FALSE;
  686. }
  687. else
  688. {
  689. // We succeeded.
  690. // The data was accepted, so notify the main context of our snapin
  691. // that it may need to update its views.
  692. CChangeNotification * pChangeNotification = new CChangeNotification();
  693. pChangeNotification->m_dwFlags = CHANGE_UPDATE_RESULT_NODE;
  694. pChangeNotification->m_pNode = m_pNodeBeingModified;
  695. pChangeNotification->m_pParentNode = m_pParentOfNodeBeingModified;
  696. HRESULT hr = PropertyChangeNotify( (LPARAM) pChangeNotification );
  697. _ASSERTE( SUCCEEDED( hr ) );
  698. // Tell the service to reload data.
  699. HRESULT hrTemp = m_spSdoServiceControl->ResetService();
  700. if( FAILED( hrTemp ) )
  701. {
  702. // Fail silently.
  703. }
  704. }
  705. }
  706. return TRUE;
  707. }
  708. //////////////////////////////////////////////////////////////////////////////
  709. /*++
  710. CLocalFileLoggingPage2::OnQueryCancel
  711. Return values:
  712. TRUE if the page can be destroyed,
  713. FALSE if the page should not be destroyed (i.e. there was invalid data)
  714. Remarks:
  715. OnQueryCancel gets called for each page in on a property sheet if that
  716. page has been visited, regardless of whether any values were changed.
  717. If you never switch to a tab, then its OnQueryCancel method will never get called.
  718. --*/
  719. //////////////////////////////////////////////////////////////////////////////
  720. BOOL CLocalFileLoggingPage2::OnQueryCancel()
  721. {
  722. ATLTRACE(_T("# CLocalFileLoggingPage2::OnQueryCancel\n"));
  723. HRESULT hr;
  724. if( m_spSdoAccounting != NULL )
  725. {
  726. // If the user wants to cancel, we should make sure that we rollback
  727. // any changes the user may have started.
  728. // If the user had not already tried to commit something,
  729. // a cancel on an SDO will hopefully be designed to be benign.
  730. hr = m_spSdoAccounting->Restore();
  731. // Don't care about the HRESULT, but it might be good to see it for debugging.
  732. }
  733. return TRUE;
  734. }
  735. //////////////////////////////////////////////////////////////////////////////
  736. /*++
  737. CLocalFileLoggingPage2::OnNewLogInterval
  738. Remarks:
  739. Called when the user clicks on the Enable Logging check box.
  740. --*/
  741. //////////////////////////////////////////////////////////////////////////////
  742. LRESULT CLocalFileLoggingPage2::OnNewLogInterval(
  743. UINT uMsg
  744. , WPARAM wParam
  745. , HWND hwnd
  746. , BOOL& bHandled
  747. )
  748. {
  749. ATLTRACE(_T("# CLocalFileLoggingPage2::OnNewLogInterval\n"));
  750. // The Enable Logging button has been checked -- check dependencies.
  751. SetLogFileFrequencyDependencies();
  752. // This return value is ignored.
  753. return TRUE;
  754. }
  755. //////////////////////////////////////////////////////////////////////////////
  756. /*++
  757. CLocalFileLoggingPage2::SetLogFileFrequencyDependencies
  758. Remarks:
  759. Utility to set state of items which may depend on the
  760. "When log file size reaches" radio button.
  761. Call whenever something changes the state of
  762. IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES
  763. or any of the other logging frequency radio buttons.
  764. --*/
  765. //////////////////////////////////////////////////////////////////////////////
  766. void CLocalFileLoggingPage2::SetLogFileFrequencyDependencies( void )
  767. {
  768. ATLTRACE(_T("# CLocalFileLoggingPage2::SetLogFileFrequencyDependencies\n"));
  769. int nLoadStringResult;
  770. TCHAR szDaily[IAS_MAX_STRING];
  771. TCHAR szWeekly[IAS_MAX_STRING];
  772. TCHAR szMonthly[IAS_MAX_STRING];
  773. TCHAR szWhenLogFileSizeReaches[IAS_MAX_STRING];
  774. nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_PAGE2__DAILY_FORMAT, szDaily, IAS_MAX_STRING );
  775. _ASSERT( nLoadStringResult > 0 );
  776. nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_PAGE2__WEEKLY_FORMAT, szWeekly, IAS_MAX_STRING );
  777. _ASSERT( nLoadStringResult > 0 );
  778. nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_PAGE2__MONTHLY_FORMAT, szMonthly, IAS_MAX_STRING );
  779. _ASSERT( nLoadStringResult > 0 );
  780. nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_SIZE_REACHES_FORMAT, szWhenLogFileSizeReaches, IAS_MAX_STRING );
  781. _ASSERT( nLoadStringResult > 0 );
  782. // Set the text to appear as the log file name.
  783. if( ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__DAILY ), BM_GETCHECK, 0, 0 ) )
  784. SetDlgItemText( IDC_STATIC_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_NAME, szDaily );
  785. else if( ::SendMessage( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WEEKLY ), BM_GETCHECK, 0, 0 ) )
  786. SetDlgItemText( IDC_STATIC_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_NAME, szWeekly );
  787. else if( ::SendMessage( GetDlgItem(IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__MONTHLY ), BM_GETCHECK, 0, 0 ) )
  788. SetDlgItemText( IDC_STATIC_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_NAME, szMonthly );
  789. else
  790. // This takes care of both the UNLIMITED and the WHEN_LOG_FILE_SIZE_REACHES case -- they both
  791. // use the same format of filename.
  792. SetDlgItemText( IDC_STATIC_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_NAME, szWhenLogFileSizeReaches );
  793. // Ascertain what the state of the IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES radio button is.
  794. int iChecked = ::SendMessage( GetDlgItem(IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES), BM_GETCHECK, 0, 0 );
  795. int iEnabled = ::IsWindowEnabled( GetDlgItem( IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__WHEN_LOG_FILE_REACHES ) );
  796. if( iChecked && iEnabled )
  797. {
  798. // Make sure the correct items are enabled.
  799. ::EnableWindow( GetDlgItem( IDC_STATIC_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE_UNITS), TRUE );
  800. ::EnableWindow( GetDlgItem( IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE), TRUE );
  801. }
  802. else
  803. {
  804. // Make sure the correct items are enabled.
  805. ::EnableWindow( GetDlgItem( IDC_STATIC_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE_UNITS), FALSE );
  806. ::EnableWindow( GetDlgItem( IDC_EDIT_LOCAL_FILE_LOGGING_PAGE2__LOG_FILE_SIZE), FALSE );
  807. }
  808. // Enable deleting old log files iff unlimited file size is not selected.
  809. iChecked = ::SendMessage(
  810. GetDlgItem(IDC_RADIO_LOCAL_FILE_LOGGING_PAGE2__UNLIMITED),
  811. BM_GETCHECK,
  812. 0,
  813. 0
  814. );
  815. ::EnableWindow(GetDlgItem(IDC_CHECK_DELETE_IF_FULL), !iChecked);
  816. }
  817. /////////////////////////////////////////////////////////////////////////////
  818. /*++
  819. CLocalFileLoggingPage2::GetHelpPath
  820. Remarks:
  821. This method is called to get the help file path within
  822. an compressed HTML document when the user presses on the Help
  823. button of a property sheet.
  824. It is an override of atlsnap.h CIASPropertyPageImpl::OnGetHelpPath.
  825. --*/
  826. //////////////////////////////////////////////////////////////////////////////
  827. HRESULT CLocalFileLoggingPage2::GetHelpPath( LPTSTR szHelpPath )
  828. {
  829. ATLTRACE(_T("# CLocalFileLoggingPage2::GetHelpPath\n"));
  830. // Check for preconditions:
  831. #ifdef UNICODE_HHCTRL
  832. // ISSUE: We seemed to have a problem with passing WCHAR's to the hhctrl.ocx
  833. // installed on this machine -- it appears to be non-unicode.
  834. lstrcpy( szHelpPath, _T("idh_proppage_local_file_logging2.htm") );
  835. #else
  836. strcpy( (CHAR *) szHelpPath, "idh_proppage_local_file_logging2.htm" );
  837. #endif
  838. return S_OK;
  839. }