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.

1283 lines
35 KiB

  1. //+=======================================================================
  2. //
  3. // File: CTest.cxx
  4. //
  5. // Purpose: Define the CTest class.
  6. //
  7. // This class is the test engine for the CreateFileMonikerEx
  8. // (CFMEx) DRTs. All interactions with monikers are handled
  9. // through the CMoniker class.
  10. //
  11. //+=======================================================================
  12. // -------------
  13. // Include Files
  14. // -------------
  15. #define _DCOM_ // Allow DCOM extensions (e.g., CoInitializeEx).
  16. #include <windows.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <wchar.h>
  20. #include <wtypes.h>
  21. #include <oaidl.h>
  22. #include <dsys.h>
  23. #include <olecairo.h>
  24. #include "CDir.hxx"
  25. #include "CMoniker.hxx"
  26. #include "CTest.hxx"
  27. //+------------------------------------------------------------------------
  28. //
  29. // Function: CTest::CTest
  30. //
  31. // Synopsis: Inititialize member variables.
  32. //
  33. // Inputs: None.
  34. //
  35. // Outputs: N/A
  36. //
  37. // Effects: All members are initialized/defaulted.
  38. //
  39. //+------------------------------------------------------------------------
  40. CTest::CTest( )
  41. {
  42. m_lError = 0L;
  43. *m_wszErrorMessage = L'\0';
  44. m_pcDirectoryOriginal = NULL;
  45. m_pcDirectoryFinal = NULL;
  46. } // CTest::CTest
  47. //+------------------------------------------------------------------------------
  48. //
  49. // Function: CTest::~CTest
  50. //
  51. // Synopsis: No action.
  52. //
  53. // Inputs: N/A
  54. //
  55. // Outputs: N/A
  56. //
  57. // Effects: None.
  58. //
  59. //+------------------------------------------------------------------------------
  60. CTest::~CTest()
  61. {
  62. } // CTest::~CTest
  63. //+-------------------------------------------------------------------------------
  64. //
  65. // Function: CTest::Initialize
  66. //
  67. // Synopsis: Inititialize a CTest object.
  68. //
  69. // Inputs: CDirectory objects representing the original and final
  70. // locations of a link source file. The original location
  71. // is used in CreateTemporaryStorage(), and the final location
  72. // is used in RenameTemporaryStorage().
  73. //
  74. // Outputs: TRUE if successful, FALSE otherwise.
  75. //
  76. // Effects: m_cDirectoryOriginal and m_cDirectoryFinal are set.
  77. //
  78. //+-------------------------------------------------------------------------------
  79. BOOL CTest::Initialize( const CDirectory& cDirectoryOriginal,
  80. const CDirectory& cDirectoryFinal
  81. )
  82. {
  83. // -----
  84. // Begin
  85. // -----
  86. m_pcDirectoryOriginal = &cDirectoryOriginal;
  87. m_pcDirectoryFinal = &cDirectoryFinal;
  88. m_cMoniker.Initialize( cDirectoryOriginal, cDirectoryFinal );
  89. // ----
  90. // Exit
  91. // ----
  92. return TRUE;
  93. } // CTest::Initialize
  94. //+-------------------------------------------------------------------------
  95. //
  96. // Function: CTest::CreateFileMonikerEx
  97. //
  98. // Synopsis: Verify that CreateFileMonikerEx actually creates a
  99. // *tracking* file moniker. This is done by creating
  100. // the file moniker, renaming the link source,
  101. // Reducing the moniker, and getting the display name
  102. // of the reduced moniker. Note that this tests
  103. // both CreateFileMonikerEx and Reduce.
  104. //
  105. // Inputs: None.
  106. //
  107. // Outputs: TRUE if successful, FALSE otherwise.
  108. //
  109. // Effects: None.
  110. //
  111. //+-------------------------------------------------------------------------
  112. BOOL CTest::CreateFileMonikerEx( )
  113. {
  114. // ---------------
  115. // Local Variables
  116. // ---------------
  117. BOOL bSuccess = FALSE;
  118. WCHAR wszDisplayName[ MAX_PATH + sizeof( L'\0' ) ];
  119. IMoniker* pmnkReduced = NULL;
  120. // -----
  121. // Begin
  122. // -----
  123. wprintf( L"CreateFileMonikerEx()\n" );
  124. wprintf( L" Create a tracking file moniker (using CreateFileMonikerEx),\n"
  125. L" move the represented file, Reduce the moniker, and get\n"
  126. L" the display name from the reduced moniker. It should be the\n"
  127. L" new file name. This test covers both CreateFileMonikerEx and\n"
  128. L" Reduce.\n" );
  129. // Create the tracking file moniker.
  130. if( !m_cMoniker.CreateFileMonikerEx( ) )
  131. EXIT( L"Could not CreateFileMonikerEx" );
  132. // Rename the link source file.
  133. if( !m_cMoniker.RenameTemporaryStorage() )
  134. EXIT( L"Could not rename the temporary storage file" );
  135. // Reduce the tracking file moniker
  136. if( !m_cMoniker.Reduce( INFINITE, &pmnkReduced ))
  137. EXIT( L"Could not reduce the moniker" );
  138. // Use the reduced (non-tracking) file moniker to get the display name.
  139. if( !m_cMoniker.GetDisplayName( wszDisplayName, pmnkReduced ))
  140. EXIT( L"Could not get the display name" );
  141. // Validate the display name.
  142. if( _wcsicmp( wszDisplayName, m_cMoniker.GetTemporaryStorageName() ))
  143. EXIT( L"Failed" );
  144. bSuccess = TRUE;
  145. // ----
  146. // Exit
  147. // ----
  148. Exit:
  149. m_cMoniker.DeleteTemporaryStorage();
  150. DisplayErrors( bSuccess, L"CTest::CreateFileMonikerEx()" );
  151. return( bSuccess );
  152. } // CTest::CreateFileMonikerEx()
  153. //+--------------------------------------------------------------------------
  154. //
  155. // Function: CTest::GetDisplayName
  156. //
  157. // Synopsis: Create a tracking file moniker, get its display name,
  158. // rename the link source file, and get the display name again.
  159. // The value of the second display name will depend on whether
  160. // or not the original and final link source are within the set
  161. // of local indexed volumes.
  162. //
  163. // Inputs: None.
  164. //
  165. // Outputs: TRUE if successful, FALSE otherwise.
  166. //
  167. // Effects: None.
  168. //
  169. //+--------------------------------------------------------------------------
  170. BOOL CTest::GetDisplayName( )
  171. {
  172. // ---------------
  173. // Local Variables
  174. // ---------------
  175. BOOL bSuccess = FALSE;
  176. WCHAR wszFinalDisplayName[ MAX_PATH + sizeof( L'\0' ) ];
  177. WCHAR wszOriginalDisplayName[ MAX_PATH + sizeof( L'\0' ) ];
  178. // -----
  179. // Begin
  180. // -----
  181. wprintf( L"GetDisplayName()\n" );
  182. wprintf( L" Create a tracking file moniker, move the represented file,\n"
  183. L" and perform a GetDisplayName on the moniker. If the original\n"
  184. L" and final locations of the source file are within the set of local\n"
  185. L" indexed drives, the display name will represent the final file name.\n"
  186. L" Otherwise, it will represent the original display name.\n" );
  187. // Create a tracking file moniker.
  188. if( !m_cMoniker.CreateFileMonikerEx( ) )
  189. EXIT( L"Could not CreateFileMonikerEx" );
  190. // Get its display name.
  191. if( !m_cMoniker.GetDisplayName( wszOriginalDisplayName ))
  192. EXIT( L"Could not get the original display name" );
  193. // Rename the link source.
  194. if( !m_cMoniker.RenameTemporaryStorage() )
  195. EXIT( L"Could not rename the temporary storage file" );
  196. // Get the renamed moniker's display name.
  197. if( !m_cMoniker.GetDisplayName( wszFinalDisplayName ))
  198. EXIT( L"Could not get the final display name" );
  199. // Was and is the link source on a local, indexed volume?
  200. if( ( m_pcDirectoryOriginal->GetFileSystemType() == fstOFS )
  201. &&
  202. ( m_pcDirectoryOriginal->GetFileSystemType() == fstOFS )
  203. )
  204. {
  205. // Yes, so the GetDisplayName should have tracked the rename.
  206. if( _wcsicmp( wszFinalDisplayName, m_cMoniker.GetTemporaryStorageName() ))
  207. EXIT( L"Failed" );
  208. }
  209. else
  210. {
  211. // No, so the GetDisplayName should have returned the original name.
  212. if( _wcsicmp( wszOriginalDisplayName, wszFinalDisplayName ))
  213. EXIT( L"Failed" );
  214. }
  215. bSuccess = TRUE;
  216. // ----
  217. // Exit
  218. // ----
  219. Exit:
  220. m_cMoniker.DeleteTemporaryStorage();
  221. DisplayErrors( bSuccess, L"CTest::GetDisplayName()" );
  222. return( bSuccess );
  223. } // CTest::GetDisplayName()
  224. //+--------------------------------------------------------------------------
  225. //
  226. // Function: CTest::GetTimeOfLastChange
  227. //
  228. // Synopsis: Create a tracking file moniker, rename it, sleep, and
  229. // touch it. If the original and final link sources are
  230. // on local, indexed volumes, then a GetDisplayName should
  231. // return the final link source's time. Otherwise, it should
  232. // return the original link source's time.
  233. //
  234. // Inputs: None.
  235. //
  236. // Outputs: TRUE if successful, FALSE otherwise.
  237. //
  238. // Effects: None.
  239. //
  240. //+--------------------------------------------------------------------------
  241. BOOL CTest::GetTimeOfLastChange( )
  242. {
  243. // ---------------
  244. // Local Variables
  245. // ---------------
  246. BOOL bSuccess = FALSE;
  247. FILETIME ftOriginal;
  248. FILETIME ftFinal;
  249. FILETIME ftMoniker;
  250. // -----
  251. // Begin
  252. // -----
  253. wprintf( L"GetTimeOfLastChange()\n" );
  254. wprintf( L" Create a tracking file moniker and move it. Then touch (set the Access\n"
  255. L" time) on the link source, and perform a GetTimeOfLastChange on the Moniker.\n"
  256. L" If the original and final location of the link source is within the set\n"
  257. L" of local indexed volumes, then the time returned from the moniker should\n"
  258. L" match that of the post-touch link source. Otherwise it should match the\n"
  259. L" link sources original time.\n" );
  260. // Create a tracking file moniker.
  261. if( !m_cMoniker.CreateFileMonikerEx( TRACK_LOCALONLY ) )
  262. EXIT( L"Could not CreateFileMonikerEx" );
  263. // Get the link source's current time.
  264. if( !m_cMoniker.GetTemporaryStorageTime( &ftOriginal ))
  265. EXIT( L"Could not get original file time" );
  266. // Move the link source.
  267. if( !m_cMoniker.RenameTemporaryStorage() )
  268. EXIT( L"Could not rename the temporary storage file" );
  269. // Delay so that when we touch the final link source, its time
  270. // will be noticably different from the original link source's time.
  271. {
  272. wprintf( L" Sleeping to let the time change: " );
  273. for( int i = 0; i < 10; i++ ) // Sleep for 5 seconds
  274. {
  275. wprintf( L"z" );
  276. Sleep( 500 ); // 1/2 second
  277. }
  278. wprintf( L"\n" );
  279. }
  280. // Touch the final link source.
  281. if( !m_cMoniker.TouchTemporaryStorage())
  282. EXIT( L"Could not touch temporary storage" );
  283. // Get the final link source's time from the file system.
  284. if( !m_cMoniker.GetTemporaryStorageTime( &ftFinal ))
  285. EXIT( L"could not get final file time" );
  286. // Get the final link source's time from the moniker.
  287. if( !m_cMoniker.GetTimeOfLastChange( &ftMoniker ))
  288. EXIT( L"Could not get the time of last change" );
  289. // Is the original & final location of the link source file
  290. // in the set of local, indexed volumes?
  291. if( ( m_pcDirectoryOriginal->GetFileSystemType() == fstOFS )
  292. &&
  293. ( m_pcDirectoryOriginal->GetFileSystemType() == fstOFS )
  294. )
  295. {
  296. // Yes. GetTimeOfLastChange should therefore have found
  297. // the time of the final link source file.
  298. if( memcmp( &ftFinal, &ftMoniker, sizeof( FILETIME ) ))
  299. EXIT( L"Failed" );
  300. }
  301. else
  302. {
  303. // No. GetTimeOfLastChange should therefore have returned
  304. // the time of the original link source file.
  305. if( memcmp( &ftOriginal, &ftMoniker, sizeof( FILETIME ) ))
  306. EXIT( L"Failed" );
  307. }
  308. bSuccess = TRUE;
  309. // ----
  310. // Exit
  311. // ----
  312. Exit:
  313. m_cMoniker.DeleteTemporaryStorage();
  314. DisplayErrors( bSuccess, L"CTest::GetTimeOfLastChange()" );
  315. return( bSuccess );
  316. } // CTest::GetTimeOfLastChange()
  317. //+--------------------------------------------------------------------
  318. //
  319. // Function: CTest::BindToObject
  320. //
  321. // Synopsis: Create a tracking file moniker, move the link source,
  322. // and attempt to bind to it with a BindToObject.
  323. // Since presumably the temporary file we're using as a link
  324. // source has no server, this will fail. But any failure
  325. // downstream of locating the link source file will be
  326. // ignored.
  327. //
  328. // Inputs: None.
  329. //
  330. // Output: TRUE if successful, FALSE otherwise.
  331. //
  332. // Effects: None.
  333. //
  334. //+--------------------------------------------------------------------
  335. BOOL CTest::BindToObject( )
  336. {
  337. // ---------------
  338. // Local Variables
  339. // ---------------
  340. BOOL bSuccess = FALSE;
  341. // -----
  342. // Begin
  343. // -----
  344. wprintf( L"BindToObject()\n" );
  345. wprintf( L" Create a tracking file moniker, moved the represented file,\n"
  346. L" and attempt a BindToStorage() (which should succeed).\n" );
  347. // Create a tracking file moniker.
  348. if( !m_cMoniker.CreateFileMonikerEx( ) )
  349. EXIT( L"Could not CreateFileMonikerEx" );
  350. // Move the link source file.
  351. if( !m_cMoniker.RenameTemporaryStorage() )
  352. EXIT( L"Could not rename the temporary storage file" );
  353. // Attempt a bind.
  354. if( !m_cMoniker.BindToObject( ))
  355. EXIT( L"Could not bind to Object" );
  356. bSuccess = TRUE;
  357. // ----
  358. // Exit
  359. // ----
  360. Exit:
  361. m_cMoniker.DeleteTemporaryStorage();
  362. DisplayErrors( bSuccess, L"CTest::BindToObject()" );
  363. return( bSuccess );
  364. } // CTest::BindToObject()
  365. //+-----------------------------------------------------------
  366. //
  367. // Function: CTest::IPersist
  368. //
  369. // Synopsis: Create a tracking file moniker, move the link
  370. // source, and perform the CMoniker::SaveDeleteLoad
  371. // test.
  372. //
  373. // Inputs: None.
  374. //
  375. // Output: TRUE if successful, FALSE otherwise
  376. //
  377. // Effects: None.
  378. //
  379. //+-----------------------------------------------------------
  380. BOOL CTest::IPersist( )
  381. {
  382. // ---------------
  383. // Local Variables
  384. // ---------------
  385. BOOL bSuccess = FALSE;
  386. // -----
  387. // Begin
  388. // -----
  389. wprintf( L"IPersist()\n" );
  390. wprintf( L" Create a tracking file moniker (using CreateFileMonikerEx), and\n"
  391. L" save it to a Stream. Delete the moniker, create a new one using\n"
  392. L" CreateFileMoniker, load it from the Stream, and verify that the resulting\n"
  393. L" file moniker is tracking.\n" );
  394. // Create a tracking file moniker.
  395. if( !m_cMoniker.CreateFileMonikerEx( ) )
  396. EXIT( L"Could not CreateFileMonikerEx" );
  397. // Rename the link source.
  398. if( !m_cMoniker.RenameTemporaryStorage() )
  399. EXIT( L"Could not rename the temporary storage file" );
  400. // Save the moniker, deleted, create a new moniker, and reload it.
  401. if( !m_cMoniker.SaveDeleteLoad( ))
  402. EXIT( L"Failed SaveDeleteLoad" );
  403. bSuccess = TRUE;
  404. // ----
  405. // Exit
  406. // ----
  407. Exit:
  408. m_cMoniker.DeleteTemporaryStorage();
  409. DisplayErrors( bSuccess, L"CTest::IPersist()" );
  410. return( bSuccess );
  411. } // CTest::IPersist()
  412. //+----------------------------------------------------------------------
  413. //
  414. // Function: CTest::ComposeWith
  415. //
  416. // Synopsis: Create a tracking file moniker, and use it in the
  417. // CMoniker::ComposeWith operation.
  418. //
  419. // Inputs: None.
  420. //
  421. // Output: TRUE if successful, FALSE otherwise.
  422. //
  423. // Effects: None.
  424. //
  425. //+----------------------------------------------------------------------
  426. BOOL CTest::ComposeWith( )
  427. {
  428. // ---------------
  429. // Local Variables
  430. // ---------------
  431. BOOL bSuccess = FALSE;
  432. IMoniker* pmnkReduced = NULL;
  433. WCHAR wszDisplayName[ MAX_PATH + sizeof( L'\0' )];
  434. // -----
  435. // Begin
  436. // -----
  437. m_lError = 0;
  438. wprintf( L"ComposeWith()\n" );
  439. wprintf( L" Create a tracking file moniker, and compose it with a non-tracking\n"
  440. L" file moniker on the right. The resulting moniker should be tracking.\n" );
  441. // Create the tracking file moniker.
  442. if( !m_cMoniker.CreateFileMonikerEx( ) )
  443. EXIT( L"Could not CreateFileMonikerEx" );
  444. // Perform the ComposeWith operation.
  445. if( !m_cMoniker.ComposeWith( ))
  446. EXIT( L"Failed ComposeWith" );
  447. // Move the link source file.
  448. if( !m_cMoniker.RenameTemporaryStorage() )
  449. EXIT( L"Could not rename the temporary storage file" );
  450. // Reduce the composed moniker.
  451. if( !m_cMoniker.Reduce( INFINITE, &pmnkReduced ))
  452. EXIT( L"Could not reduce the moniker" );
  453. // Get the display name on the reduced moniker.
  454. if( !m_cMoniker.GetDisplayName( wszDisplayName, pmnkReduced ))
  455. EXIT( L"Could not get the display name" );
  456. // Verify that the name from the moniker is the actual link source
  457. // file's new name.
  458. if( _wcsicmp( wszDisplayName, m_cMoniker.GetTemporaryStorageName() ))
  459. EXIT( L"Failed" );
  460. bSuccess = TRUE;
  461. // ----
  462. // Exit
  463. // ----
  464. Exit:
  465. m_cMoniker.DeleteTemporaryStorage();
  466. DisplayErrors( bSuccess, L"CTest::ComposeWith()" );
  467. return( bSuccess );
  468. } // CTest::ComposeWith()
  469. //+------------------------------------------------------------------
  470. //
  471. // Function: CTest::BindToStorage
  472. //
  473. // Synopsis: Create a tracking file moniker, and perform the
  474. // CMoniker::BindToStorage operation.
  475. //
  476. // Inputs: None.
  477. //
  478. // Output: TRUE if successful, FALSE otherwise.
  479. //
  480. //+------------------------------------------------------------------
  481. BOOL CTest::BindToStorage( )
  482. {
  483. // ---------------
  484. // Local Variables
  485. // ---------------
  486. BOOL bSuccess = FALSE;
  487. // -----
  488. // Begin
  489. // -----
  490. m_lError = 0;
  491. wprintf( L"BindToStorage()\n" );
  492. wprintf( L" Create a tracking file moniker (using CreateFileMonikerEx),\n"
  493. L" move the represented file, Reduce the moniker, and get\n"
  494. L" the display name from the reduced moniker. It should be the\n"
  495. L" new file name. This test covers both CreateFileMonikerEx and\n"
  496. L" Reduce.\n" );
  497. // Create the tracking file moniker.
  498. if( !m_cMoniker.CreateFileMonikerEx( ) )
  499. EXIT( L"Could not CreateFileMonikerEx" );
  500. // Move the link source file.
  501. if( !m_cMoniker.RenameTemporaryStorage() )
  502. EXIT( L"Could not rename the temporary storage file" );
  503. // Bind to the Storage
  504. if( !m_cMoniker.BindToStorage( ))
  505. EXIT( L"Could not bind to Storage" );
  506. bSuccess = TRUE;
  507. // ----
  508. // Exit
  509. // ----
  510. Exit:
  511. m_cMoniker.DeleteTemporaryStorage();
  512. DisplayErrors( bSuccess, L"CTest::BindToStorage()" );
  513. return( bSuccess );
  514. } // CTest::BindToStorage()
  515. //+--------------------------------------------------------------------------
  516. //
  517. // Function: CTest::DeleteLinkSource
  518. //
  519. // Synopsis: Create a tracking file moniker, delete the link source,
  520. // and attempt a Reduce. The Reduce should not fail, but
  521. // it should return an HResult of MK_S_REDUCED_TO_SELF.
  522. //
  523. // Inputs: Tick count limit on the length of the Reduce operation.
  524. //
  525. // Output: TRUE if successful, FALSE otherwise.
  526. //
  527. // Effects: None.
  528. //
  529. //+--------------------------------------------------------------------------
  530. BOOL CTest::DeleteLinkSource( DWORD dwDelay )
  531. {
  532. // ---------------
  533. // Local Variables
  534. // ---------------
  535. BOOL bSuccess = FALSE;
  536. WCHAR wszTimeout[ 80 ];
  537. // -----
  538. // Begin
  539. // -----
  540. m_lError = 0L;
  541. // Generate a string which shows what the delay is.
  542. switch( dwDelay )
  543. {
  544. case 0:
  545. wcscpy( wszTimeout, L"instant timeout" );
  546. break;
  547. case INFINITE:
  548. wcscpy( wszTimeout, L"infinite timeout" );
  549. break;
  550. default:
  551. wsprintf( wszTimeout, L"%d ms timeout", dwDelay );
  552. }
  553. // Display a header.
  554. wprintf( L"Delete Link Source (%s)\n",
  555. wszTimeout );
  556. wprintf( L" Create a tracking file moniker, then delete the link source, and\n"
  557. L" attempt a reduce with a %s.\n",
  558. wszTimeout );
  559. // Create a tracking file moniker.
  560. if( !m_cMoniker.CreateFileMonikerEx( ) )
  561. EXIT( L"Could not CreateFileMonikerEx" );
  562. // Delete the link source file.
  563. if( !m_cMoniker.DeleteTemporaryStorage() )
  564. EXIT( L"Could not delete temporary storage" );
  565. // Tell CMoniker not to alarm the user with error messages.
  566. m_cMoniker.SuppressErrorMessages( TRUE );
  567. // Reduce the moniker, and verify it returns the proper Success code.
  568. if( !m_cMoniker.Reduce( dwDelay )
  569. ||
  570. m_cMoniker.GetHResult() != MK_S_REDUCED_TO_SELF
  571. )
  572. EXIT( L"Failed" );
  573. bSuccess = TRUE;
  574. // ----
  575. // Exit
  576. // ----
  577. Exit:
  578. m_cMoniker.DeleteTemporaryStorage();
  579. m_cMoniker.SuppressErrorMessages( FALSE );
  580. DisplayErrors( bSuccess, L"CTest::DeleteLinkSource()" );
  581. return( bSuccess );
  582. } // CTest::DeleteLinkSource()
  583. //+------------------------------------------------------------------
  584. //
  585. // Function: CTest::GetOversizedBindOpts
  586. //
  587. // Synopsis: Test a bind context's ability to return a BIND_OPTS
  588. // which is larger than expected.
  589. //
  590. // First, initialize the default BIND_OPTS in the bind
  591. // context to 1s. Then, ask for a large BIND_OPTS.
  592. // The resulting buffer should have 1s up to the size of
  593. // the normal BIND_OPTS, and 0s for the remainder of the
  594. // buffer. The length, however, should be that of the large
  595. // buffer.
  596. //
  597. // Inputs: None.
  598. //
  599. // Outputs: TRUE if successful, FALSE otherwise.
  600. //
  601. // Effects: None.
  602. //
  603. //+------------------------------------------------------------------
  604. BOOL CTest::GetOversizedBindOpts( )
  605. {
  606. // ---------------
  607. // Local Variables
  608. // ---------------
  609. BOOL bSuccess = FALSE;
  610. BIND_OPTS bind_opts;
  611. LPBIND_OPTS pbind_optsLarge = (LPBIND_OPTS) new BYTE[ SIZE_OF_LARGE_BIND_OPTS ];
  612. LPBIND_OPTS pbind_optsExpected = (LPBIND_OPTS) new BYTE[ SIZE_OF_LARGE_BIND_OPTS ];
  613. // -----
  614. // Begin
  615. // -----
  616. m_lError = 0L;
  617. wprintf( L"Get Oversized BindOpts\n" );
  618. wprintf( L" Create a buffer which is much larger than a normal BIND_OPTS, and\n"
  619. L" use it to request the BIND_OPTS from a bind context. The length\n"
  620. L" of the resulting buffer should be the large value, and the extra\n"
  621. L" room in the buffer should be all 0s.\n" );
  622. // Validate our 'new' operations.
  623. if( pbind_optsLarge == NULL )
  624. EXIT( L"Could not allocate pbind_optsLarge" );
  625. pbind_optsLarge->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  626. if( pbind_optsExpected == NULL )
  627. EXIT( L"Could not allocate pbind_optsExpected" );
  628. pbind_optsExpected->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  629. // Initialize the bind_opts (normal sized) in the bind context to 1s.
  630. if( !m_cMoniker.InitializeBindContext() )
  631. EXIT( L"Could not initialize the bind context" );
  632. memset( &bind_opts, 1, sizeof( bind_opts ));
  633. bind_opts.cbStruct = sizeof( bind_opts );;
  634. m_lError = m_cMoniker.GetBindCtx()->SetBindOptions( &bind_opts );
  635. if( FAILED( m_lError )) EXIT( L"Could not set original bind options" );
  636. // Initialize the large bind_opts to 2s, then retrieve the bind_opts into
  637. // this structure. This is done to verify that the GetBindOptions below
  638. // fills in the entire requested buffer (overwirting all of the 2s).
  639. memset( pbind_optsLarge, 2, SIZE_OF_LARGE_BIND_OPTS );
  640. pbind_optsLarge->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  641. m_lError = m_cMoniker.GetBindCtx()->GetBindOptions( pbind_optsLarge );
  642. if( FAILED( m_lError )) EXIT( L"Could not get large bind options" );
  643. // The returned structure should have the large cbStruct, 1s up to
  644. // the length of BIND_OPTS, and 0s after that.
  645. memset( pbind_optsExpected, 0, SIZE_OF_LARGE_BIND_OPTS );
  646. memset( pbind_optsExpected, 1, sizeof( bind_opts ));
  647. pbind_optsExpected->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  648. if( memcmp( pbind_optsLarge, pbind_optsExpected, SIZE_OF_LARGE_BIND_OPTS ))
  649. EXIT( L"Failed" );
  650. bSuccess = TRUE;
  651. // ----
  652. // Exit
  653. // ----
  654. Exit:
  655. DisplayErrors( bSuccess, L"CTest::GetOversizedBindOpts()" );
  656. return( bSuccess );
  657. } // CTest::GetOversizeBindOpts()
  658. //+----------------------------------------------------------------
  659. //
  660. // Function: CTest::GetUndersizedBindOpts
  661. //
  662. // Synopsis: Create a bind context, and initialize the data in its
  663. // BIND_OPTS to 1s. Create a normal BIND_OPTS-sized buffer,
  664. // initialize it to 2s, then use it to get a small-sized
  665. // BIND_OPTS from the bind context. The resulting buffer
  666. // should have a small length, a small number of 1s,
  667. // and 2s for the remainder of the buffer.
  668. //
  669. // Inputs: None.
  670. //
  671. // Outputs: TRUE if successful, FALSE otherwise.
  672. //
  673. // Effects: None.
  674. //
  675. //+----------------------------------------------------------------
  676. BOOL CTest::GetUndersizedBindOpts( )
  677. {
  678. // ---------------
  679. // Local Variables
  680. // ---------------
  681. BOOL bSuccess = FALSE;
  682. LPBIND_OPTS pbind_optsSmall = (LPBIND_OPTS) new BYTE[ SIZE_OF_LARGE_BIND_OPTS ];
  683. LPBIND_OPTS pbind_optsExpected = (LPBIND_OPTS) new BYTE[ SIZE_OF_LARGE_BIND_OPTS ];
  684. BIND_OPTS bind_opts;
  685. bind_opts.cbStruct = sizeof( bind_opts );
  686. // -----
  687. // Begin
  688. // -----
  689. m_lError = 0L;
  690. wprintf( L"Get Undersized BindOpts\n" );
  691. wprintf( L" Get the BIND_OPTS from a bind context, but only providing a small\n"
  692. L" buffer, and verify that only that portion of the actual BIND_OPTS\n"
  693. L" is returned.\n" );
  694. // Validate our 'new's.
  695. if( pbind_optsSmall == NULL )
  696. EXIT( L"Could not allocate pbind_optsSmall" );
  697. pbind_optsSmall->cbStruct = SIZE_OF_SMALL_BIND_OPTS;
  698. if( pbind_optsExpected == NULL )
  699. EXIT( L"Could not allocate pbind_optsExpected" );
  700. pbind_optsExpected->cbStruct = SIZE_OF_SMALL_BIND_OPTS;
  701. // Initialize the bind_opts (normal sized) in the bind context to 1s.
  702. if( !m_cMoniker.InitializeBindContext() )
  703. EXIT( L"Could not initialize the bind context" );
  704. memset( &bind_opts, 1, sizeof( bind_opts ));
  705. bind_opts.cbStruct = sizeof( bind_opts );;
  706. m_lError = m_cMoniker.GetBindCtx()->SetBindOptions( &bind_opts );
  707. if( FAILED( m_lError )) EXIT( L"Could not set original bind options" );
  708. // Initialize the small bind_opts to 2s, then retrieve the bind_opts into
  709. // this structure.
  710. memset( pbind_optsSmall, 2, SIZE_OF_LARGE_BIND_OPTS );
  711. pbind_optsSmall->cbStruct = SIZE_OF_SMALL_BIND_OPTS;
  712. m_lError = m_cMoniker.GetBindCtx()->GetBindOptions( pbind_optsSmall );
  713. if( FAILED( m_lError )) EXIT( L"Could not get small bind options" );
  714. // The returned structure should have the small cbStruct, 1s up to
  715. // the end of the small buffer, and 2s to the end of the real buffer.
  716. memset( pbind_optsExpected, 2, SIZE_OF_LARGE_BIND_OPTS );
  717. memset( pbind_optsExpected, 1, SIZE_OF_SMALL_BIND_OPTS );
  718. pbind_optsExpected->cbStruct = SIZE_OF_SMALL_BIND_OPTS;
  719. if( memcmp( pbind_optsSmall, pbind_optsExpected, SIZE_OF_LARGE_BIND_OPTS ))
  720. EXIT( L"Failed" );
  721. bSuccess = TRUE;
  722. // ----
  723. // Exit
  724. // ----
  725. Exit:
  726. DisplayErrors( bSuccess, L"CTest::GetUndersizedBindOpts()" );
  727. return( bSuccess );
  728. } // CTest::GetUndersizedBindOpts()
  729. //+----------------------------------------------------------------
  730. //
  731. // Function: CTest::SetOversizedBindOpts
  732. //
  733. // Synopsis: Create a large BIND_OPTS buffer, set it in
  734. // a bind context, and verify that it can be read back.
  735. //
  736. // Inputs: None.
  737. //
  738. // Outputs: TRUE if successful, FALSE otherwise.
  739. //
  740. // Effects: None.
  741. //
  742. //+----------------------------------------------------------------
  743. BOOL CTest::SetOversizedBindOpts( )
  744. {
  745. // ---------------
  746. // Local Variables
  747. // ---------------
  748. BOOL bSuccess = FALSE;
  749. LPBIND_OPTS pbind_optsLarge = (LPBIND_OPTS) new BYTE[ SIZE_OF_LARGE_BIND_OPTS ];
  750. LPBIND_OPTS pbind_optsExpected = (LPBIND_OPTS) new BYTE[ SIZE_OF_LARGE_BIND_OPTS ];
  751. // -----
  752. // Begin
  753. // -----
  754. wprintf( L"Set Oversized BindOpts\n" );
  755. wprintf( L" Set a larger-than-usual BIND_OPTS in a bind context, and verify\n"
  756. L" that it can be read back in its entirety.\n" );
  757. // Validate our 'new's.
  758. if( pbind_optsLarge == NULL )
  759. EXIT( L"Could not allocate pbind_optsLarge" );
  760. pbind_optsLarge->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  761. if( pbind_optsExpected == NULL )
  762. EXIT( L"Could not allocate pbind_optsExpected" );
  763. pbind_optsExpected->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  764. // Initialize the large bind_opts to 1s, then set the large BIND_OPTS
  765. // into the bind context.
  766. if( !m_cMoniker.InitializeBindContext() )
  767. EXIT( L"Could not initialize the bind context" );
  768. memset( pbind_optsLarge, 1, SIZE_OF_LARGE_BIND_OPTS );
  769. pbind_optsLarge->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  770. m_lError = m_cMoniker.GetBindCtx()->SetBindOptions( pbind_optsLarge );
  771. if( FAILED( m_lError )) EXIT( L"Could not set large bind options" );
  772. // Get the BIND_OPTS back from the bind context, and verify that it's
  773. // what we set.
  774. memset( pbind_optsLarge, 0, SIZE_OF_LARGE_BIND_OPTS );
  775. pbind_optsLarge->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  776. m_lError = m_cMoniker.GetBindCtx()->GetBindOptions( pbind_optsLarge );
  777. memset( pbind_optsExpected, 1, SIZE_OF_LARGE_BIND_OPTS );
  778. pbind_optsExpected->cbStruct = SIZE_OF_LARGE_BIND_OPTS;
  779. if( memcmp( pbind_optsLarge, pbind_optsExpected, SIZE_OF_LARGE_BIND_OPTS ))
  780. EXIT( L"Failed" );
  781. bSuccess = TRUE;
  782. // ----
  783. // Exit
  784. // ----
  785. Exit:
  786. DisplayErrors( bSuccess, L"CTest::SetOversizedBindOpts()" );
  787. return( bSuccess );
  788. } // CTest::SetOversizeBindOpts()
  789. //+------------------------------------------------------------
  790. //
  791. // Function: CTest::SetUndersizedBindOpts
  792. //
  793. // Synopsis: Create a bind context, and initialize its BIND_OPTS to
  794. // all 1s. Then, set a small BIND_OPTS in the bind context
  795. // which is set to 2s. Read back the whold BIND_OPTS, and
  796. // verify that it has the normal length, 2s at the
  797. // beginning, and 1s to the end.
  798. //
  799. // Inputs: None.
  800. //
  801. // Output: TRUE if successful, FALSE otherwise.
  802. //
  803. //+------------------------------------------------------------
  804. BOOL CTest::SetUndersizedBindOpts( )
  805. {
  806. // ---------------
  807. // Local Variables
  808. // ---------------
  809. BOOL bSuccess = FALSE;
  810. BIND_OPTS bind_opts;
  811. BIND_OPTS bind_optsExpected;
  812. // -----
  813. // Begin
  814. // -----
  815. m_lError = 0L;
  816. wprintf( L"Set Undersized BindOpts\n" );
  817. wprintf( L" Initialize a BIND_OPTS in a bind context to 1s, then set a smaller\n"
  818. L" BIND_OPTS in it set to 2s. When the buffer is read back, it should\n"
  819. L" have 2s up to the small buffer size, followed by 1s.\n" );
  820. // Initialize the bind context's BIND_OPTS (normal sized) to 1s.
  821. if( !m_cMoniker.InitializeBindContext() )
  822. EXIT( L"Could not initialize the bind context" );
  823. memset( &bind_opts, 1, sizeof( bind_opts ));
  824. bind_opts.cbStruct = sizeof( bind_opts );
  825. m_lError = m_cMoniker.GetBindCtx()->SetBindOptions( &bind_opts );
  826. if( FAILED( m_lError )) EXIT( L"Could not set initial BIND_OPTS" );
  827. // Now set a smaller BIND_OPTS. But initialize the local BIND_OPTS to all
  828. // 2s, so that we can verify that only part of the buffer is put into the
  829. // bind context.
  830. memset( &bind_opts, 2, sizeof( bind_opts ) );
  831. bind_opts.cbStruct = SIZE_OF_SMALL_BIND_OPTS;
  832. m_lError = m_cMoniker.GetBindCtx()->SetBindOptions( &bind_opts );
  833. if( FAILED( m_lError )) EXIT( L"Could not set small BIND_OPTS" );
  834. // The resulting BIND_OPTS in the bind context should have 2s up
  835. // to SIZE_OF_SMALL_BIND_OPTS, and 1s for the remainder of the buffer.
  836. bind_opts.cbStruct = sizeof( bind_opts );
  837. m_lError = m_cMoniker.GetBindCtx()->GetBindOptions( &bind_opts );
  838. if( FAILED( m_lError )) EXIT( L"Could not get BIND_OPTS" );
  839. memset( &bind_optsExpected, 1, sizeof( bind_opts ));
  840. memset( &bind_optsExpected, 2, SIZE_OF_SMALL_BIND_OPTS );
  841. bind_optsExpected.cbStruct = sizeof( bind_opts );
  842. if( memcmp( &bind_opts, &bind_optsExpected, sizeof( bind_opts )))
  843. EXIT( L"Failed" );
  844. bSuccess = TRUE;
  845. // ----
  846. // Exit
  847. // ----
  848. Exit:
  849. DisplayErrors( bSuccess, L"CTest::SetUndersizedBindOpts()" );
  850. return( bSuccess );
  851. } // CTest::SetUndersizedBindOpts()
  852. #ifdef _FUTURE_
  853. BOOL CTest::CFMWithRegistryClear( )
  854. {
  855. BOOL bSuccess = FALSE;
  856. WCHAR wszDisplayName[ MAX_PATH + sizeof( L'\0' ) ];
  857. if( !m_cMoniker.SaveRegistryTrackFlags() )
  858. EXIT( L"Could not save the existing track flags in the registry" );
  859. if( !m_cMoniker.DeleteRegistryTrackFlags() )
  860. EXIT( L"Could not delete the existing track flags in the registry" );
  861. if( !m_cMoniker.CreateFileMoniker() )
  862. EXIT( L"Could not CreateFileMoniker" );
  863. if( !m_cMoniker.RenameTemporaryStorage() )
  864. EXIT( L"Could not rename the temporary storage file" );
  865. if( !m_cMoniker.GetDisplayName( wszDisplayName ))
  866. EXIT( L"Could not get the display name" );
  867. if( !_wcsicmp( wszDisplayName, m_cMoniker.GetTemporaryStorageName() ))
  868. EXIT( L"Test failed: A moniker was created using CreateFileMoniker, after\n"
  869. L" the Track Flags had been cleared from the Registry.\n"
  870. L" The underlying root storage was then renamed.\n"
  871. L" But a GetDisplayName then showed the new name, implying\n"
  872. L" that the created moniker is using tracking (which it\n"
  873. L" should not, because without the Track Flags set there\n"
  874. L" should be no tracking).\n" );
  875. bSuccess = TRUE;
  876. Exit:
  877. m_cMoniker.DeleteTemporaryStorage();
  878. if( !m_cMoniker.RestoreRegistryTrackFlags() )
  879. ERROR_IN_EXIT( L"Could not restore Track Flags in Registry" );
  880. DisplayErrors( bSuccess, L"CTest::CFMWithRegistryClear" );
  881. return( bSuccess );
  882. } // CTest::CFMWithRegistryClear
  883. BOOL CTest::CFMWithRegistrySet( )
  884. {
  885. BOOL bSuccess = FALSE;
  886. WCHAR wszDisplayName[ MAX_PATH + sizeof( L'\0' ) ];
  887. if( !m_cMoniker.SaveRegistryTrackFlags() )
  888. EXIT( L"Could not save the existing track flags in the registry" );
  889. if( !m_cMoniker.SetTrackFlagsInRegistry( TRACK_LOCALONLY ) )
  890. EXIT( L"Could not set track flags in the registry" );
  891. if( !m_cMoniker.CreateFileMoniker() )
  892. EXIT( L"Could not CreateFileMoniker" );
  893. if( !m_cMoniker.RenameTemporaryStorage() )
  894. EXIT( L"Could not rename the temporary storage file" );
  895. if( !m_cMoniker.GetDisplayName( wszDisplayName ))
  896. EXIT( L"Could not get the display name" );
  897. if( _wcsicmp( wszDisplayName, m_cMoniker.GetTemporaryStorageName() ))
  898. EXIT( L"Test failed: A moniker was created using CreateFileMoniker, after\n"
  899. L" setting the TRACK_LOCALONLY flag in the Registry.\n"
  900. L" However, after moving the linked file, GetDisplayName\n"
  901. L" did not return the new name.\n" );
  902. bSuccess = TRUE;
  903. Exit:
  904. m_cMoniker.DeleteTemporaryStorage();
  905. if( !m_cMoniker.RestoreRegistryTrackFlags() )
  906. ERROR_IN_EXIT( L"Could not restore Track Flags in Registry" );
  907. DisplayErrors( bSuccess, L"CTest::CFMWithRegistrySet()" );
  908. return( bSuccess );
  909. } // CTest::CFMWithRegistrySet
  910. #endif // _FUTURE_