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.

1288 lines
39 KiB

  1. /*++
  2. Copyright (C) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. GLOBALS.CPP
  5. Abstract:
  6. Utility methods for the Performance Logs and Alerts MMC snap-in.
  7. --*/
  8. #include "stdAfx.h"
  9. #include <pdhmsg.h> // For CreateSampleFileName
  10. #include <pdhp.h> // For CreateSampleFileName
  11. #include "smcfgmsg.h"
  12. #include "globals.h"
  13. USE_HANDLE_MACROS("SMLOGCFG(globals.cpp)");
  14. extern "C" {
  15. WCHAR GUIDSTR_TypeLibrary[] = {L"{7478EF60-8C46-11d1-8D99-00A0C913CAD4}"};
  16. WCHAR GUIDSTR_ComponentData[] = {L"{7478EF61-8C46-11d1-8D99-00A0C913CAD4}"};
  17. WCHAR GUIDSTR_Component[] = {L"{7478EF62-8C46-11d1-8D99-00A0C913CAD4}"};
  18. WCHAR GUIDSTR_RootNode[] = {L"{7478EF63-8C46-11d1-8D99-00A0C913CAD4}"};
  19. WCHAR GUIDSTR_MainNode[] = {L"{7478EF64-8C46-11d1-8D99-00A0C913CAD4}"}; // Obsolete after Beta 3
  20. WCHAR GUIDSTR_SnapInExt[] = {L"{7478EF65-8C46-11d1-8D99-00A0C913CAD4}"};
  21. WCHAR GUIDSTR_CounterMainNode[] = {L"{7478EF66-8C46-11d1-8D99-00A0C913CAD4}"};
  22. WCHAR GUIDSTR_TraceMainNode[] = {L"{7478EF67-8C46-11d1-8D99-00A0C913CAD4}"};
  23. WCHAR GUIDSTR_AlertMainNode[] = {L"{7478EF68-8C46-11d1-8D99-00A0C913CAD4}"};
  24. WCHAR GUIDSTR_PerformanceAbout[] = {L"{7478EF69-8C46-11d1-8D99-00A0C913CAD4}"};
  25. };
  26. HINSTANCE g_hinst; // Global instance handle
  27. CRITICAL_SECTION g_critsectInstallDefaultQueries;
  28. const COMBO_BOX_DATA_MAP TimeUnitCombo[] =
  29. {
  30. {SLQ_TT_UTYPE_SECONDS, IDS_SECONDS},
  31. {SLQ_TT_UTYPE_MINUTES, IDS_MINUTES},
  32. {SLQ_TT_UTYPE_HOURS, IDS_HOURS},
  33. {SLQ_TT_UTYPE_DAYS, IDS_DAYS}
  34. };
  35. const DWORD dwTimeUnitComboEntries = sizeof(TimeUnitCombo)/sizeof(TimeUnitCombo[0]);
  36. //---------------------------------------------------------------------------
  37. // Returns the current object based on the s_cfMmcMachineName clipboard format
  38. //
  39. CDataObject*
  40. ExtractOwnDataObject
  41. (
  42. LPDATAOBJECT lpDataObject // [in] IComponent pointer
  43. )
  44. {
  45. HGLOBAL hGlobal;
  46. HRESULT hr = S_OK;
  47. CDataObject* pDO = NULL;
  48. hr = ExtractFromDataObject( lpDataObject,
  49. CDataObject::s_cfInternal,
  50. sizeof(CDataObject **),
  51. &hGlobal
  52. );
  53. if( SUCCEEDED(hr) )
  54. {
  55. pDO = *(CDataObject **)(hGlobal);
  56. ASSERT( NULL != pDO );
  57. VERIFY ( NULL == GlobalFree(hGlobal) ); // Must return NULL
  58. }
  59. return pDO;
  60. } // end ExtractOwnDataObject()
  61. //---------------------------------------------------------------------------
  62. // Extracts data based on the passed-in clipboard format
  63. //
  64. HRESULT
  65. ExtractFromDataObject
  66. (
  67. LPDATAOBJECT lpDataObject, // [in] Points to data object
  68. UINT cfClipFormat, // [in] Clipboard format to use
  69. ULONG nByteCount, // [in] Number of bytes to allocate
  70. HGLOBAL *phGlobal // [out] Points to the data we want
  71. )
  72. {
  73. ASSERT( NULL != lpDataObject );
  74. HRESULT hr = S_OK;
  75. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  76. FORMATETC formatetc = { (USHORT)cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  77. *phGlobal = NULL;
  78. do
  79. {
  80. // Allocate memory for the stream
  81. stgmedium.hGlobal = GlobalAlloc( GMEM_SHARE, nByteCount );
  82. if( !stgmedium.hGlobal )
  83. {
  84. hr = E_OUTOFMEMORY;
  85. LOCALTRACE( L"Out of memory\n" );
  86. break;
  87. }
  88. // Attempt to get data from the object
  89. hr = lpDataObject->GetDataHere( &formatetc, &stgmedium );
  90. if (FAILED(hr))
  91. {
  92. break;
  93. }
  94. // stgmedium now has the data we need
  95. *phGlobal = stgmedium.hGlobal;
  96. stgmedium.hGlobal = NULL;
  97. } while (0);
  98. if (FAILED(hr) && stgmedium.hGlobal)
  99. {
  100. VERIFY ( NULL == GlobalFree(stgmedium.hGlobal)); // Must return NULL
  101. }
  102. return hr;
  103. } // end ExtractFromDataObject()
  104. //---------------------------------------------------------------------------
  105. //
  106. VOID DisplayError( LONG nErrorCode, LPWSTR wszDlgTitle )
  107. {
  108. LPVOID lpMsgBuf = NULL;
  109. ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  110. NULL,
  111. nErrorCode,
  112. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  113. (LPWSTR)&lpMsgBuf,
  114. 0,
  115. NULL
  116. );
  117. if (lpMsgBuf) {
  118. ::MessageBox( NULL, (LPWSTR)lpMsgBuf, wszDlgTitle,
  119. MB_OK|MB_ICONINFORMATION );
  120. LocalFree( lpMsgBuf );
  121. }
  122. } // end DisplayError()
  123. VOID DisplayError( LONG nErrorCode, UINT nTitleString )
  124. {
  125. CString strTitle;
  126. LPVOID lpMsgBuf = NULL;
  127. ResourceStateManager rsm;
  128. ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  129. NULL,
  130. nErrorCode,
  131. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  132. (LPWSTR)&lpMsgBuf,
  133. 0,
  134. NULL
  135. );
  136. strTitle.LoadString ( nTitleString );
  137. if (lpMsgBuf) {
  138. ::MessageBox( NULL, (LPWSTR)lpMsgBuf, (LPCWSTR)strTitle,
  139. MB_OK|MB_ICONINFORMATION );
  140. LocalFree( lpMsgBuf );
  141. }
  142. } // end DisplayError()
  143. //---------------------------------------------------------------------------
  144. // Debug only message box
  145. //
  146. int DebugMsg( LPWSTR wszMsg, LPWSTR wszTitle )
  147. {
  148. int nRetVal = 0;
  149. wszMsg;
  150. wszTitle;
  151. #ifdef _DEBUG
  152. nRetVal = ::MessageBox( NULL, wszMsg, wszTitle, MB_OK );
  153. #endif
  154. return nRetVal;
  155. }
  156. //---------------------------------------------------------------------------
  157. // Extracts data based on the passed-in clipboard format
  158. HRESULT ExtractObjectTypeGUID( IDataObject* piDataObject, GUID* pguidObjectType )
  159. {
  160. HGLOBAL hGlobal;
  161. HRESULT hr = S_OK;
  162. hr = ExtractFromDataObject( piDataObject,
  163. CDataObject::s_cfNodeType,
  164. sizeof(GUID),
  165. &hGlobal
  166. );
  167. if( SUCCEEDED(hr) )
  168. {
  169. *pguidObjectType = *(GUID*)(hGlobal);
  170. ASSERT( NULL != pguidObjectType );
  171. VERIFY ( NULL == GlobalFree(hGlobal) ); // Must return NULL
  172. }
  173. return hr;
  174. }
  175. HRESULT
  176. ExtractMachineName(
  177. IDataObject* piDataObject,
  178. CString& rstrMachineName )
  179. {
  180. HRESULT hr = S_OK;
  181. HGLOBAL hMachineName;
  182. hr = ExtractFromDataObject(piDataObject,
  183. CDataObject::s_cfMmcMachineName,
  184. sizeof(WCHAR) * (MAX_PATH + 1),
  185. &hMachineName);
  186. if( SUCCEEDED(hr) )
  187. {
  188. LPWSTR pszNewData = reinterpret_cast<LPWSTR>(hMachineName);
  189. if (NULL == pszNewData)
  190. {
  191. ASSERT(FALSE);
  192. hr = E_UNEXPECTED;
  193. } else {
  194. //
  195. // Null terminate just to be safe.
  196. //
  197. pszNewData[MAX_PATH] = L'\0';
  198. rstrMachineName = pszNewData;
  199. VERIFY ( NULL == GlobalFree(hMachineName) ); // Must return NULL
  200. }
  201. }
  202. return hr;
  203. }
  204. DWORD __stdcall
  205. CreateSampleFileName (
  206. const CString& rstrQueryName,
  207. const CString& rstrMachineName,
  208. const CString& rstrFolderName,
  209. const CString& rstrInputBaseName,
  210. const CString& rstrSqlName,
  211. DWORD dwSuffixValue,
  212. DWORD dwLogFileTypeValue,
  213. DWORD dwCurrentSerialNumber,
  214. CString& rstrReturnName)
  215. {
  216. DWORD dwStatus = ERROR_SUCCESS;
  217. PPDH_PLA_INFO pInfo = NULL;
  218. DWORD dwStrBufLen = 0;
  219. DWORD dwInfoSize = 0;
  220. DWORD dwFlags = 0;
  221. rstrReturnName.Empty();
  222. dwStatus = PdhPlaGetInfo(
  223. (LPWSTR)(LPCWSTR)rstrQueryName,
  224. (LPWSTR)(LPCWSTR)rstrMachineName,
  225. &dwInfoSize,
  226. pInfo );
  227. if( ERROR_SUCCESS == dwStatus && 0 != dwInfoSize ){
  228. pInfo = (PPDH_PLA_INFO)malloc(dwInfoSize);
  229. if( NULL != pInfo && (sizeof(PDH_PLA_INFO) <= dwInfoSize) ){
  230. ZeroMemory( pInfo, dwInfoSize );
  231. pInfo->dwMask = PLA_INFO_CREATE_FILENAME;
  232. dwStatus = PdhPlaGetInfo(
  233. (LPWSTR)(LPCWSTR)rstrQueryName,
  234. (LPWSTR)(LPCWSTR)rstrMachineName,
  235. &dwInfoSize,
  236. pInfo );
  237. pInfo->dwMask = PLA_INFO_CREATE_FILENAME;
  238. pInfo->dwFileFormat = dwLogFileTypeValue;
  239. pInfo->strBaseFileName = (LPWSTR)(LPCWSTR)rstrInputBaseName;
  240. pInfo->dwAutoNameFormat = dwSuffixValue;
  241. // PLA_INFO_FLAG_TYPE is counter log vs trace log vs alert
  242. pInfo->strDefaultDir = (LPWSTR)(LPCWSTR)rstrFolderName;
  243. pInfo->dwLogFileSerialNumber = dwCurrentSerialNumber;
  244. pInfo->strSqlName = (LPWSTR)(LPCWSTR)rstrSqlName;
  245. pInfo->dwLogFileSerialNumber = dwCurrentSerialNumber;
  246. // Create file name based on passed parameters only.
  247. dwFlags = PLA_FILENAME_CREATEONLY; // PLA_FILENAME_CURRENTLOG for latest run log
  248. dwStatus = PdhPlaGetLogFileName (
  249. (LPWSTR)(LPCWSTR)rstrQueryName,
  250. (LPWSTR)(LPCWSTR)rstrMachineName,
  251. pInfo,
  252. dwFlags,
  253. &dwStrBufLen,
  254. NULL );
  255. if ( ERROR_SUCCESS == dwStatus || PDH_INSUFFICIENT_BUFFER == dwStatus ) {
  256. dwStatus = PdhPlaGetLogFileName (
  257. (LPWSTR)(LPCWSTR)rstrQueryName,
  258. (LPWSTR)(LPCWSTR)rstrMachineName,
  259. pInfo,
  260. dwFlags,
  261. &dwStrBufLen,
  262. rstrReturnName.GetBufferSetLength ( dwStrBufLen ) );
  263. rstrReturnName.ReleaseBuffer();
  264. }
  265. }
  266. }
  267. if ( NULL != pInfo ) {
  268. free( pInfo );
  269. }
  270. return dwStatus;
  271. }
  272. DWORD __stdcall
  273. IsDirPathValid (
  274. CString& rstrDefault,
  275. CString& rstrPath,
  276. BOOL bLastNameIsDirectory,
  277. BOOL bCreateMissingDirs,
  278. BOOL& rbIsValid )
  279. /*++
  280. Routine Description:
  281. Creates the directory specified in szPath and any other "higher"
  282. directories in the specified path that don't exist.
  283. Arguments:
  284. IN CString rstrDefault
  285. The default log file folder
  286. IN CString rstrPath
  287. directory path to create (assumed to be a DOS path, not a UNC)
  288. IN BOOL bLastNameIsDirectory
  289. TRUE when the last name in the path is a Directory and not a File
  290. FALSE if the last name is a file
  291. IN BOOL bCreateMissingDirs
  292. TRUE will create any dirs in the path that are not found
  293. FALSE will only test for existence and not create any
  294. missing dirs.
  295. OUT BOOL rbIsValid
  296. TRUE if the directory path now exists
  297. FALSE if error (GetLastError to find out why)
  298. Return Value:
  299. DWSTATUS
  300. --*/
  301. {
  302. CString strLocalPath;
  303. LPWSTR szLocalPath;
  304. LPWSTR szEnd;
  305. DWORD dwAttr;
  306. WCHAR cBackslash = L'\\';
  307. DWORD dwStatus = ERROR_SUCCESS;
  308. rbIsValid = FALSE;
  309. szLocalPath = strLocalPath.GetBufferSetLength ( MAX_PATH );
  310. if ( NULL == szLocalPath ) {
  311. dwStatus = ERROR_OUTOFMEMORY;
  312. } else {
  313. if (GetFullPathName (
  314. rstrPath,
  315. MAX_PATH,
  316. szLocalPath,
  317. NULL) > 0) {
  318. //
  319. // Check for prefix
  320. //
  321. // Go one past the first backslash after the drive or remote machine name
  322. // N.B. We are assuming the full path name looks like either "\\machine\share\..."
  323. // or "C:\xxx". How about "\\?\xxx" style names
  324. //
  325. if ( cBackslash == szLocalPath[0] && cBackslash == szLocalPath[1] ) {
  326. szEnd = &szLocalPath[2];
  327. while ((*szEnd != cBackslash) && (*szEnd != 0) ) szEnd++;
  328. if ( cBackslash == *szEnd ) {
  329. szEnd++;
  330. }
  331. } else {
  332. szEnd = &szLocalPath[3];
  333. }
  334. if (*szEnd != L'\0') {
  335. int iPathLen;
  336. iPathLen = lstrlen(szEnd) - 1;
  337. while (iPathLen >= 0 && cBackslash == szEnd[iPathLen]) {
  338. szEnd[iPathLen] = L'\0';
  339. iPathLen -= 1;
  340. }
  341. // then there are sub dirs to create
  342. while (*szEnd != L'\0') {
  343. // go to next backslash
  344. while ((*szEnd != cBackslash) && (*szEnd != L'\0')) szEnd++;
  345. if (*szEnd == cBackslash) {
  346. // terminate path here and create directory
  347. *szEnd = L'\0';
  348. if (bCreateMissingDirs) {
  349. if (!CreateDirectory (szLocalPath, NULL)) {
  350. // see what the error was and "adjust" it if necessary
  351. dwStatus = GetLastError();
  352. if ( ERROR_ALREADY_EXISTS == dwStatus ) {
  353. // this is OK
  354. dwStatus = ERROR_SUCCESS;
  355. rbIsValid = TRUE;
  356. } else {
  357. rbIsValid = FALSE;
  358. }
  359. } else {
  360. // directory created successfully so update count
  361. rbIsValid = TRUE;
  362. }
  363. } else {
  364. if ((dwAttr = GetFileAttributes(szLocalPath)) != 0xFFFFFFFF) {
  365. //
  366. // make sure it's a dir
  367. // N.B. Why not simply use if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)??
  368. // Special purpose?
  369. //
  370. if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) ==
  371. FILE_ATTRIBUTE_DIRECTORY) {
  372. rbIsValid = TRUE;
  373. } else {
  374. // if any dirs fail, then clear the return value
  375. rbIsValid = FALSE;
  376. }
  377. } else {
  378. // if any dirs fail, then clear the return value
  379. rbIsValid = FALSE;
  380. }
  381. }
  382. // replace backslash and go to next dir
  383. *szEnd++ = cBackslash;
  384. }
  385. }
  386. // create last dir in path now if it's a dir name and not a filename
  387. if (bLastNameIsDirectory) {
  388. if (bCreateMissingDirs) {
  389. BOOL fDirectoryCreated;
  390. rstrDefault.MakeLower();
  391. strLocalPath.MakeLower();
  392. if (rstrDefault == strLocalPath) {
  393. fDirectoryCreated = PerfCreateDirectory (szLocalPath);
  394. } else {
  395. fDirectoryCreated = CreateDirectory (szLocalPath, NULL);
  396. }
  397. if (!fDirectoryCreated) {
  398. // see what the error was and "adjust" it if necessary
  399. dwStatus = GetLastError();
  400. if ( ERROR_ALREADY_EXISTS == dwStatus ) {
  401. // this is OK
  402. dwStatus = ERROR_SUCCESS;
  403. rbIsValid = TRUE;
  404. } else {
  405. rbIsValid = FALSE;
  406. }
  407. } else {
  408. // directory created successfully
  409. rbIsValid = TRUE;
  410. }
  411. } else {
  412. if ((dwAttr = GetFileAttributes(szLocalPath)) != 0xFFFFFFFF) {
  413. //
  414. // make sure it's a dir
  415. // N.B. Why not simply use if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)??
  416. // Special purpose?
  417. //
  418. if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) ==
  419. FILE_ATTRIBUTE_DIRECTORY) {
  420. rbIsValid = TRUE;
  421. } else {
  422. // if any dirs fail, then clear the return value
  423. rbIsValid = FALSE;
  424. }
  425. } else {
  426. // if any dirs fail, then clear the return value
  427. rbIsValid = FALSE;
  428. }
  429. }
  430. }
  431. } else {
  432. // else this is a root dir only so return success.
  433. dwStatus = ERROR_SUCCESS;
  434. rbIsValid = TRUE;
  435. }
  436. }
  437. strLocalPath.ReleaseBuffer();
  438. }
  439. return dwStatus;
  440. }
  441. DWORD __stdcall
  442. ProcessDirPath (
  443. const CString& rstrDefault,
  444. CString& rstrPath,
  445. const CString& rstrLogName,
  446. CWnd* pwndParent,
  447. BOOL& rbIsValid,
  448. BOOL bOnFilesPage )
  449. {
  450. DWORD dwStatus = ERROR_SUCCESS;
  451. DWORD cchLen;
  452. CString strExpanded;
  453. CString strDefaultFolder;
  454. LPWSTR szExpanded;
  455. DWORD cchExpandedLen;
  456. ResourceStateManager rsm;
  457. // Parse all environment symbols
  458. cchLen = 0;
  459. cchLen = ExpandEnvironmentStrings ( rstrPath, NULL, 0 );
  460. if ( 0 < cchLen ) {
  461. MFC_TRY
  462. //
  463. // CString size does not include NULL.
  464. // cchLen includes NULL. Include NULL count for safety.
  465. //
  466. szExpanded = strExpanded.GetBuffer ( cchLen );
  467. MFC_CATCH_DWSTATUS;
  468. if ( ERROR_SUCCESS == dwStatus ) {
  469. cchExpandedLen = ExpandEnvironmentStrings (
  470. rstrPath,
  471. szExpanded,
  472. cchLen);
  473. if ( 0 == cchExpandedLen ) {
  474. dwStatus = GetLastError();
  475. }
  476. }
  477. strExpanded.ReleaseBuffer();
  478. } else {
  479. dwStatus = GetLastError();
  480. }
  481. if ( ERROR_SUCCESS == dwStatus ) {
  482. //
  483. // Get the default log file folder.(It must have already been expanded)
  484. //
  485. strDefaultFolder = rstrDefault;
  486. dwStatus = IsDirPathValid (strDefaultFolder,
  487. strExpanded,
  488. TRUE,
  489. FALSE,
  490. rbIsValid);
  491. }
  492. if ( ERROR_SUCCESS != dwStatus ) {
  493. rbIsValid = FALSE;
  494. } else {
  495. if ( !rbIsValid ) {
  496. INT nMbReturn;
  497. CString strMessage;
  498. MFC_TRY
  499. strMessage.Format ( IDS_FILE_DIR_NOT_FOUND, rstrPath );
  500. nMbReturn = pwndParent->MessageBox ( strMessage, rstrLogName, MB_YESNO | MB_ICONWARNING );
  501. if (nMbReturn == IDYES) {
  502. // create the dir(s)
  503. dwStatus = IsDirPathValid (strDefaultFolder,
  504. strExpanded,
  505. TRUE,
  506. TRUE,
  507. rbIsValid);
  508. if (ERROR_SUCCESS != dwStatus || !rbIsValid ) {
  509. // unable to create the dir, display message
  510. if ( bOnFilesPage ) {
  511. strMessage.Format ( IDS_FILE_DIR_NOT_MADE, rstrPath );
  512. } else {
  513. strMessage.Format ( IDS_DIR_NOT_MADE, rstrPath );
  514. }
  515. nMbReturn = pwndParent->MessageBox ( strMessage, rstrLogName, MB_OK | MB_ICONERROR);
  516. rbIsValid = FALSE;
  517. }
  518. } else if ( IDNO == nMbReturn ) {
  519. // then abort and return to the dialog
  520. if ( bOnFilesPage ) {
  521. strMessage.LoadString ( IDS_FILE_DIR_CREATE_CANCEL );
  522. } else {
  523. strMessage.LoadString ( IDS_DIR_CREATE_CANCEL );
  524. }
  525. nMbReturn = pwndParent->MessageBox ( strMessage, rstrLogName, MB_OK | MB_ICONINFORMATION);
  526. rbIsValid = FALSE;
  527. }
  528. MFC_CATCH_DWSTATUS
  529. } // else the path is OK
  530. }
  531. return dwStatus;
  532. }
  533. DWORD __stdcall
  534. IsCommandFilePathValid (
  535. CString& rstrPath )
  536. {
  537. DWORD dwStatus = ERROR_SUCCESS;
  538. ResourceStateManager rsm;
  539. if ( !rstrPath.IsEmpty() ) {
  540. HANDLE hOpenFile;
  541. hOpenFile = CreateFile (
  542. rstrPath,
  543. GENERIC_READ,
  544. 0, // Not shared
  545. NULL, // Security attributes
  546. OPEN_EXISTING, //
  547. FILE_ATTRIBUTE_NORMAL,
  548. NULL );
  549. if ( ( NULL == hOpenFile )
  550. || INVALID_HANDLE_VALUE == hOpenFile ) {
  551. dwStatus = SMCFG_NO_COMMAND_FILE_FOUND;
  552. } else {
  553. CloseHandle(hOpenFile);
  554. }
  555. } else {
  556. dwStatus = SMCFG_NO_COMMAND_FILE_FOUND;
  557. }
  558. return dwStatus;
  559. }
  560. INT __stdcall
  561. BrowseCommandFilename (
  562. CWnd* pwndParent,
  563. CString& rstrFilename )
  564. {
  565. INT iReturn = IDCANCEL;
  566. OPENFILENAME ofn;
  567. CString strInitialDir;
  568. WCHAR szFileName[MAX_PATH + 1];
  569. WCHAR szDrive[MAX_PATH + 1];
  570. WCHAR szDir[MAX_PATH + 1];
  571. WCHAR szExt[MAX_PATH + 1];
  572. WCHAR szFileFilter[MAX_PATH + 1];
  573. LPWSTR szNextFilter;
  574. CString strTemp;
  575. ResourceStateManager rsm;
  576. _wsplitpath((LPCWSTR)rstrFilename,
  577. szDrive, szDir, szFileName, szExt);
  578. strInitialDir = szDrive;
  579. strInitialDir += szDir;
  580. lstrcat (szFileName, szExt);
  581. ZeroMemory( &ofn, sizeof( OPENFILENAME ) );
  582. ofn.lStructSize = sizeof(ofn);
  583. ofn.hwndOwner = pwndParent->m_hWnd;
  584. ofn.hInstance = GetModuleHandle(NULL);
  585. // load the file filter MSZ
  586. szNextFilter = &szFileFilter[0];
  587. strTemp.LoadString ( IDS_BROWSE_CMD_FILE_FILTER1 );
  588. lstrcpyW (szNextFilter, (LPCWSTR)strTemp);
  589. szNextFilter += strTemp.GetLength();
  590. *szNextFilter++ = 0;
  591. strTemp.LoadString ( IDS_BROWSE_CMD_FILE_FILTER2 );
  592. lstrcpyW (szNextFilter, (LPCWSTR)strTemp);
  593. szNextFilter += strTemp.GetLength();
  594. *szNextFilter++ = 0;
  595. strTemp.LoadString ( IDS_BROWSE_CMD_FILE_FILTER3 );
  596. lstrcpyW (szNextFilter, (LPCWSTR)strTemp);
  597. szNextFilter += strTemp.GetLength();
  598. *szNextFilter++ = 0;
  599. strTemp.LoadString ( IDS_BROWSE_CMD_FILE_FILTER4 );
  600. lstrcpyW (szNextFilter, (LPCWSTR)strTemp);
  601. szNextFilter += strTemp.GetLength();
  602. *szNextFilter++ = 0;
  603. *szNextFilter++ = 0; // msz terminator
  604. ofn.lpstrFilter = szFileFilter;
  605. ofn.lpstrCustomFilter = NULL;
  606. ofn.nMaxCustFilter = 0;
  607. ofn.nFilterIndex = 1; // nFilterIndex is 1-based
  608. ofn.lpstrFile = szFileName;
  609. ofn.nMaxFile = MAX_PATH;
  610. ofn.lpstrFileTitle = NULL;
  611. ofn.nMaxFileTitle = 0;
  612. ofn.lpstrInitialDir = (LPCWSTR)strInitialDir;
  613. strTemp.LoadString( IDS_BROWSE_CMD_FILE_CAPTION );
  614. ofn.lpstrTitle = (LPCWSTR)strTemp;
  615. ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  616. ofn.nFileOffset = 0;
  617. ofn.nFileExtension = 0;
  618. ofn.lpstrDefExt = NULL;
  619. ofn.lCustData = 0;
  620. ofn.lpfnHook = NULL;
  621. ofn.lpTemplateName = NULL;
  622. iReturn = GetOpenFileName (&ofn);
  623. if ( IDOK == iReturn ) {
  624. // Update the fields with the new information
  625. rstrFilename = szFileName;
  626. } // else ignore if they canceled out
  627. return iReturn;
  628. }
  629. DWORD __stdcall
  630. FormatSmLogCfgMessage (
  631. CString& rstrMessage,
  632. HINSTANCE hResourceHandle,
  633. UINT uiMessageId,
  634. ... )
  635. {
  636. DWORD dwStatus = ERROR_SUCCESS;
  637. LPWSTR lpszTemp = NULL;
  638. // format message into temporary buffer lpszTemp
  639. va_list argList;
  640. va_start(argList, uiMessageId);
  641. dwStatus = ::FormatMessage (
  642. FORMAT_MESSAGE_FROM_HMODULE
  643. | FORMAT_MESSAGE_ALLOCATE_BUFFER
  644. | FORMAT_MESSAGE_MAX_WIDTH_MASK,
  645. hResourceHandle,
  646. uiMessageId,
  647. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  648. (LPWSTR)&lpszTemp,
  649. 0,
  650. &argList );
  651. if ( 0 != dwStatus && NULL != lpszTemp ) {
  652. rstrMessage.GetBufferSetLength( lstrlen (lpszTemp) + 1 );
  653. rstrMessage.ReleaseBuffer();
  654. rstrMessage = lpszTemp;
  655. } else {
  656. dwStatus = GetLastError();
  657. }
  658. if ( NULL != lpszTemp ) {
  659. LocalFree( lpszTemp);
  660. lpszTemp = NULL;
  661. }
  662. va_end(argList);
  663. return dwStatus;
  664. }
  665. BOOL __stdcall
  666. FileRead (
  667. HANDLE hFile,
  668. void* lpMemory,
  669. DWORD nAmtToRead)
  670. {
  671. BOOL bSuccess ;
  672. DWORD nAmtRead ;
  673. bSuccess = ReadFile (hFile, lpMemory, nAmtToRead, &nAmtRead, NULL) ;
  674. return (bSuccess && (nAmtRead == nAmtToRead)) ;
  675. } // FileRead
  676. BOOL __stdcall
  677. FileWrite (
  678. HANDLE hFile,
  679. void* lpMemory,
  680. DWORD nAmtToWrite)
  681. {
  682. BOOL bSuccess = FALSE;
  683. DWORD nAmtWritten = 0;
  684. DWORD dwFileSizeLow, dwFileSizeHigh;
  685. LONGLONG llResultSize;
  686. dwFileSizeLow = GetFileSize (hFile, &dwFileSizeHigh);
  687. // limit file size to 2GB
  688. if (dwFileSizeHigh > 0) {
  689. SetLastError (ERROR_WRITE_FAULT);
  690. bSuccess = FALSE;
  691. } else {
  692. // note that the error return of this function is 0xFFFFFFFF
  693. // since that is > the file size limit, this will be interpreted
  694. // as an error (a size error) so it's accounted for in the following
  695. // test.
  696. llResultSize = dwFileSizeLow + nAmtToWrite;
  697. if (llResultSize >= 0x80000000) {
  698. SetLastError (ERROR_WRITE_FAULT);
  699. bSuccess = FALSE;
  700. } else {
  701. // write buffer to file
  702. bSuccess = WriteFile (hFile, lpMemory, nAmtToWrite, &nAmtWritten, NULL) ;
  703. if (bSuccess) bSuccess = (nAmtWritten == nAmtToWrite ? TRUE : FALSE);
  704. }
  705. }
  706. return (bSuccess) ;
  707. } // FileWrite
  708. static
  709. DWORD _stdcall
  710. CheckDuplicateInstances (
  711. PDH_COUNTER_PATH_ELEMENTS* pFirst,
  712. PDH_COUNTER_PATH_ELEMENTS* pSecond )
  713. {
  714. DWORD dwStatus = ERROR_SUCCESS;
  715. ASSERT ( 0 == lstrcmpi ( pFirst->szMachineName, pSecond->szMachineName ) );
  716. ASSERT ( 0 == lstrcmpi ( pFirst->szObjectName, pSecond->szObjectName ) );
  717. if ( 0 == lstrcmpi ( pFirst->szInstanceName, pSecond->szInstanceName ) ) {
  718. if ( 0 == lstrcmpi ( pFirst->szParentInstance, pSecond->szParentInstance ) ) {
  719. if ( pFirst->dwInstanceIndex == pSecond->dwInstanceIndex ) {
  720. dwStatus = SMCFG_DUPL_SINGLE_PATH;
  721. }
  722. }
  723. } else if ( 0 == lstrcmpi ( pFirst->szInstanceName, L"*" ) ) {
  724. dwStatus = SMCFG_DUPL_FIRST_IS_WILD;
  725. } else if ( 0 == lstrcmpi ( pSecond->szInstanceName, L"*" ) ) {
  726. dwStatus = SMCFG_DUPL_SECOND_IS_WILD;
  727. }
  728. return dwStatus;
  729. }
  730. //++
  731. // Description:
  732. // The function checks the relation between two counter paths
  733. //
  734. // Parameter:
  735. // pFirst - First counter path
  736. // pSecond - Second counter path
  737. //
  738. // Return:
  739. // ERROR_SUCCESS - The two counter paths are different
  740. // SMCFG_DUPL_FIRST_IS_WILD - The first counter path has wildcard name
  741. // SMCFG_DUPL_SECOND_IS_WILD - The second counter path has wildcard name
  742. // SMCFG_DUPL_SINGLE_PATH - The two counter paths are the same(may include
  743. // wildcard name)
  744. //
  745. //--
  746. DWORD _stdcall
  747. CheckDuplicateCounterPaths (
  748. PDH_COUNTER_PATH_ELEMENTS* pFirst,
  749. PDH_COUNTER_PATH_ELEMENTS* pSecond )
  750. {
  751. DWORD dwStatus = ERROR_SUCCESS;
  752. if ( 0 == lstrcmpi ( pFirst->szMachineName, pSecond->szMachineName ) ) {
  753. if ( 0 == lstrcmpi ( pFirst->szObjectName, pSecond->szObjectName ) ) {
  754. if ( 0 == lstrcmpi ( pFirst->szCounterName, pSecond->szCounterName ) ) {
  755. dwStatus = CheckDuplicateInstances ( pFirst, pSecond );
  756. } else if ( 0 == lstrcmpi ( pFirst->szCounterName, L"*" )
  757. || 0 == lstrcmpi ( pSecond->szCounterName, L"*" ) ) {
  758. // Wildcard counter.
  759. BOOL bIsDuplicate = ( ERROR_SUCCESS != CheckDuplicateInstances ( pFirst, pSecond ) );
  760. if ( bIsDuplicate ) {
  761. if ( 0 == lstrcmpi ( pFirst->szCounterName, L"*" ) ) {
  762. dwStatus = SMCFG_DUPL_FIRST_IS_WILD;
  763. } else if ( 0 == lstrcmpi ( pSecond->szCounterName, L"*" ) ) {
  764. dwStatus = SMCFG_DUPL_SECOND_IS_WILD;
  765. }
  766. }
  767. }
  768. }
  769. }
  770. return dwStatus;
  771. };
  772. // This routine extracts the filename portion from a given full-path filename
  773. LPWSTR _stdcall
  774. ExtractFileName (LPWSTR pFileSpec)
  775. {
  776. LPWSTR pFileName = NULL ;
  777. WCHAR DIRECTORY_DELIMITER1 = L'\\' ;
  778. WCHAR DIRECTORY_DELIMITER2 = L':' ;
  779. if (pFileSpec)
  780. {
  781. pFileName = pFileSpec + lstrlen (pFileSpec) ;
  782. while (*pFileName != DIRECTORY_DELIMITER1 &&
  783. *pFileName != DIRECTORY_DELIMITER2)
  784. {
  785. if (pFileName == pFileSpec)
  786. {
  787. // done when no directory delimiter is found
  788. break ;
  789. }
  790. pFileName-- ;
  791. }
  792. if (*pFileName == DIRECTORY_DELIMITER1 ||
  793. *pFileName == DIRECTORY_DELIMITER2)
  794. {
  795. // directory delimiter found, point the
  796. // filename right after it
  797. pFileName++ ;
  798. }
  799. }
  800. return pFileName ;
  801. } // ExtractFileName
  802. //+--------------------------------------------------------------------------
  803. //
  804. // Function: InvokeWinHelp
  805. //
  806. // Synopsis: Helper (ahem) function to invoke winhelp.
  807. //
  808. // Arguments: [message] - WM_CONTEXTMENU or WM_HELP
  809. // [wParam] - depends on [message]
  810. // [wszHelpFileName] - filename with or without path
  811. // [adwControlIdToHelpIdMap] - see WinHelp API
  812. //
  813. // History: 06-10-1997 DavidMun Created
  814. //
  815. //---------------------------------------------------------------------------
  816. VOID
  817. InvokeWinHelp(
  818. UINT message,
  819. WPARAM wParam,
  820. LPARAM lParam,
  821. const CString& rstrHelpFileName,
  822. DWORD adwControlIdToHelpIdMap[])
  823. {
  824. //TRACE_FUNCTION(InvokeWinHelp);
  825. ASSERT ( !rstrHelpFileName.IsEmpty() );
  826. ASSERT ( adwControlIdToHelpIdMap );
  827. switch (message)
  828. {
  829. case WM_CONTEXTMENU: // Right mouse click - "What's This" context menu
  830. {
  831. ASSERT ( wParam );
  832. if ( 0 != GetDlgCtrlID ( (HWND) wParam ) ) {
  833. WinHelp(
  834. (HWND) wParam,
  835. rstrHelpFileName,
  836. HELP_CONTEXTMENU,
  837. (DWORD_PTR)adwControlIdToHelpIdMap);
  838. }
  839. }
  840. break;
  841. case WM_HELP: // Help from the "?" dialog
  842. {
  843. const LPHELPINFO pHelpInfo = (LPHELPINFO) lParam;
  844. if (pHelpInfo ) {
  845. if ( pHelpInfo->iContextType == HELPINFO_WINDOW ) {
  846. WinHelp(
  847. (HWND) pHelpInfo->hItemHandle,
  848. rstrHelpFileName,
  849. HELP_WM_HELP,
  850. (DWORD_PTR) adwControlIdToHelpIdMap);
  851. }
  852. }
  853. break;
  854. }
  855. default:
  856. //Dbg(DEB_ERROR, "Unexpected message %uL\n", message);
  857. break;
  858. }
  859. }
  860. BOOL
  861. FileNameIsValid ( CString* pstrFileName )
  862. {
  863. LPWSTR pSrc;
  864. BOOL bRetVal = TRUE;
  865. if (pstrFileName == NULL) {
  866. return FALSE;
  867. }
  868. pSrc = pstrFileName->GetBuffer(0);
  869. while (*pSrc != L'\0') {
  870. if (*pSrc == L'?' ||
  871. *pSrc == L'\\' ||
  872. *pSrc == L'*' ||
  873. *pSrc == L'|' ||
  874. *pSrc == L'<' ||
  875. *pSrc == L'>' ||
  876. *pSrc == L'/' ||
  877. *pSrc == L':' ||
  878. *pSrc == L'\"' ) {
  879. bRetVal = FALSE;
  880. break;
  881. }
  882. pSrc++;
  883. }
  884. return bRetVal;
  885. }
  886. DWORD
  887. FormatSystemMessage (
  888. DWORD dwMessageId,
  889. CString& rstrSystemMessage )
  890. {
  891. DWORD dwStatus = ERROR_SUCCESS;
  892. HINSTANCE hPdh = NULL;
  893. DWORD dwFlags = 0;
  894. LPWSTR pszMessage = NULL;
  895. DWORD dwChars;
  896. rstrSystemMessage.Empty();
  897. dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM;
  898. hPdh = LoadLibrary( L"PDH.DLL" );
  899. if ( NULL != hPdh ) {
  900. dwFlags |= FORMAT_MESSAGE_FROM_HMODULE;
  901. }
  902. dwChars = FormatMessage (
  903. dwFlags,
  904. hPdh,
  905. dwMessageId,
  906. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  907. (LPWSTR)&pszMessage,
  908. 0,
  909. NULL );
  910. if ( NULL != hPdh ) {
  911. FreeLibrary( hPdh );
  912. }
  913. if ( 0 == dwChars ) {
  914. dwStatus = GetLastError();
  915. }
  916. MFC_TRY
  917. if ( NULL != pszMessage ) {
  918. if ( L'\0' != pszMessage[0] ) {
  919. rstrSystemMessage = pszMessage;
  920. }
  921. }
  922. MFC_CATCH_DWSTATUS
  923. if ( rstrSystemMessage.IsEmpty() ) {
  924. MFC_TRY
  925. rstrSystemMessage.Format ( L"0x%08lX", dwMessageId );
  926. MFC_CATCH_DWSTATUS
  927. }
  928. LocalFree ( pszMessage );
  929. return dwStatus;
  930. }
  931. // The routines below were blatently stolen without remorse from the ole
  932. // sources in \nt\private\ole32\com\class\compapi.cxx.
  933. //
  934. //+-------------------------------------------------------------------------
  935. //
  936. // Function: HexStringToDword (private)
  937. //
  938. // Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
  939. // return value in Value; check for chDelim;
  940. //
  941. // Arguments: [lpsz] - the hex string to convert
  942. // [Value] - the returned value
  943. // [cDigits] - count of digits
  944. //
  945. // Returns: TRUE for success
  946. //
  947. //--------------------------------------------------------------------------
  948. BOOL HexStringToDword(LPCWSTR lpsz, DWORD * RetValue,
  949. int cDigits, WCHAR chDelim)
  950. {
  951. int Count;
  952. DWORD Value;
  953. Value = 0;
  954. for (Count = 0; Count < cDigits; Count++, lpsz++)
  955. {
  956. if (*lpsz >= '0' && *lpsz <= '9')
  957. Value = (Value << 4) + *lpsz - '0';
  958. else if (*lpsz >= 'A' && *lpsz <= 'F')
  959. Value = (Value << 4) + *lpsz - 'A' + 10;
  960. else if (*lpsz >= 'a' && *lpsz <= 'f')
  961. Value = (Value << 4) + *lpsz - 'a' + 10;
  962. else
  963. return(FALSE);
  964. }
  965. *RetValue = Value;
  966. if (chDelim != 0)
  967. return *lpsz++ == chDelim;
  968. else
  969. return TRUE;
  970. }
  971. //+-------------------------------------------------------------------------
  972. //
  973. // Function: wUUIDFromString (internal)
  974. //
  975. // Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000
  976. //
  977. // Arguments: [lpsz] - Supplies the UUID string to convert
  978. // [pguid] - Returns the GUID.
  979. //
  980. // Returns: TRUE if successful
  981. //
  982. //--------------------------------------------------------------------------
  983. BOOL wUUIDFromString(LPCWSTR lpsz, LPGUID pguid)
  984. {
  985. DWORD dw;
  986. if (!HexStringToDword(lpsz, &pguid->Data1, sizeof(DWORD)*2, '-'))
  987. return FALSE;
  988. lpsz += sizeof(DWORD)*2 + 1;
  989. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  990. return FALSE;
  991. lpsz += sizeof(WORD)*2 + 1;
  992. pguid->Data2 = (WORD)dw;
  993. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  994. return FALSE;
  995. lpsz += sizeof(WORD)*2 + 1;
  996. pguid->Data3 = (WORD)dw;
  997. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  998. return FALSE;
  999. lpsz += sizeof(BYTE)*2;
  1000. pguid->Data4[0] = (BYTE)dw;
  1001. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, '-'))
  1002. return FALSE;
  1003. lpsz += sizeof(BYTE)*2+1;
  1004. pguid->Data4[1] = (BYTE)dw;
  1005. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1006. return FALSE;
  1007. lpsz += sizeof(BYTE)*2;
  1008. pguid->Data4[2] = (BYTE)dw;
  1009. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1010. return FALSE;
  1011. lpsz += sizeof(BYTE)*2;
  1012. pguid->Data4[3] = (BYTE)dw;
  1013. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1014. return FALSE;
  1015. lpsz += sizeof(BYTE)*2;
  1016. pguid->Data4[4] = (BYTE)dw;
  1017. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1018. return FALSE;
  1019. lpsz += sizeof(BYTE)*2;
  1020. pguid->Data4[5] = (BYTE)dw;
  1021. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1022. return FALSE;
  1023. lpsz += sizeof(BYTE)*2;
  1024. pguid->Data4[6] = (BYTE)dw;
  1025. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1026. return FALSE;
  1027. lpsz += sizeof(BYTE)*2;
  1028. pguid->Data4[7] = (BYTE)dw;
  1029. return TRUE;
  1030. }
  1031. //+-------------------------------------------------------------------------
  1032. //
  1033. // Function: wGUIDFromString (internal)
  1034. //
  1035. // Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000}
  1036. //
  1037. // Arguments: [lpsz] - the guid string to convert
  1038. // [pguid] - guid to return
  1039. //
  1040. // Returns: TRUE if successful
  1041. //
  1042. //--------------------------------------------------------------------------
  1043. BOOL wGUIDFromString(LPCWSTR lpsz, LPGUID pguid)
  1044. {
  1045. if (*lpsz == '{' )
  1046. lpsz++;
  1047. if(wUUIDFromString(lpsz, pguid) != TRUE)
  1048. return FALSE;
  1049. lpsz +=36;
  1050. if (*lpsz == '}' )
  1051. lpsz++;
  1052. if (*lpsz != '\0') // check for zero terminated string - test bug #18307
  1053. {
  1054. return FALSE;
  1055. }
  1056. return TRUE;
  1057. }
  1058. void
  1059. KillString( CString& str )
  1060. {
  1061. LONG nSize = str.GetLength();
  1062. for( LONG i=0;i<nSize;i++ ){
  1063. str.SetAt( i, '*');
  1064. }
  1065. }
  1066. ResourceStateManager::ResourceStateManager ()
  1067. : m_hResInstance ( NULL )
  1068. {
  1069. AFX_MODULE_STATE* pModuleState;
  1070. HINSTANCE hNewResourceHandle;
  1071. pModuleState = AfxGetModuleState();
  1072. if ( NULL != pModuleState ) {
  1073. m_hResInstance = pModuleState->m_hCurrentResourceHandle;
  1074. hNewResourceHandle = (HINSTANCE)GetModuleHandleW (_CONFIG_DLL_NAME_W_);
  1075. pModuleState->m_hCurrentResourceHandle = hNewResourceHandle;
  1076. }
  1077. }
  1078. ResourceStateManager::~ResourceStateManager ()
  1079. {
  1080. AFX_MODULE_STATE* pModuleState;
  1081. pModuleState = AfxGetModuleState();
  1082. if ( NULL != pModuleState ) {
  1083. pModuleState->m_hCurrentResourceHandle = m_hResInstance;
  1084. }
  1085. }