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.

629 lines
18 KiB

  1. //+------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993.
  5. //
  6. // File: bm_Link.cxx
  7. //
  8. // Contents: Profile methods which manipulate Links, i.e. interface IOleLink
  9. //
  10. // Classes: CIOLTest
  11. //
  12. // Functions:
  13. //
  14. // History:
  15. //
  16. //--------------------------------------------------------------------------
  17. #include <headers.cxx>
  18. #pragma hdrstop
  19. #include "hlp_util.hxx"
  20. #include "hlp_iocs.hxx"
  21. #include "hlp_ias.hxx"
  22. #include "hlp_app.hxx"
  23. #include "hlp_site.hxx"
  24. #include "hlp_doc.hxx"
  25. #include "bm_link.hxx"
  26. //**********************************************************************
  27. //
  28. // CIOLTest::Name, SetUp, Run, CleanUp
  29. //
  30. // Purpose:
  31. //
  32. // These routines provide the implementation for the Name, Setup,
  33. // Run and CleanUp of the class CIOLTest. For details see the doc
  34. // for driver what are these routines supposed to do.
  35. //
  36. // Parameters:
  37. //
  38. //
  39. // Return Value:
  40. //
  41. // None
  42. //
  43. //
  44. // Comments:
  45. // If STRESS is defined don't do anything with timer variable! We are
  46. // not interested in time values.
  47. //
  48. //********************************************************************
  49. TCHAR *CIOLTest::Name ()
  50. {
  51. return TEXT("IOLTest");
  52. }
  53. SCODE CIOLTest::Setup (CTestInput *pInput)
  54. {
  55. CTestBase::Setup(pInput);
  56. HRESULT sc;
  57. HRESULT hres;
  58. #ifdef STRESS
  59. //If stress condition loop number of time = STRESSCOUNT
  60. m_ulIterations = STRESSCOUNT;
  61. #else
  62. // get iteration count
  63. m_ulIterations = pInput->GetIterations(Name());
  64. #endif
  65. #ifndef STRESS
  66. // initialize timing arrays
  67. INIT_LINKRESULTS(m_ulOleLinkSr32);
  68. INIT_LINKRESULTS(m_ulOleLinkOutl);
  69. #endif
  70. sc = OleInitialize(NULL);
  71. if (FAILED(sc))
  72. {
  73. Log (TEXT("Setup - OleInitialize failed."), sc);
  74. return sc;
  75. }
  76. hres = CLSIDFromString(L"Sr32test", &m_clsidSr32);
  77. Log (TEXT("CLSIDFromString returned ."), hres);
  78. if (hres != NOERROR)
  79. return E_FAIL;
  80. hres = CLSIDFromString(OutlineClassName, &m_clsidOutl);
  81. Log (TEXT("CLSIDFromString returned ."), hres);
  82. if (hres != NOERROR)
  83. return E_FAIL;
  84. //CreateLink Doc and Root Storage
  85. m_lpDoc = CSimpleDoc::Create();
  86. for (ULONG iIter=0; iIter<m_ulIterations; iIter++)
  87. {
  88. // CreateLink an instance of Site
  89. CSimpleSite *pObj = CSimpleSite::Create(m_lpDoc, iIter);
  90. if (pObj)
  91. m_pSite[iIter] = pObj;
  92. }
  93. return sc;
  94. }
  95. SCODE CIOLTest::Cleanup ()
  96. {
  97. for (ULONG iIter=0; iIter<m_ulIterations; iIter++)
  98. {
  99. delete m_pSite[iIter];
  100. }
  101. OleUninitialize();
  102. return S_OK;
  103. }
  104. //**********************************************************************
  105. //
  106. // CIOLTest::Run
  107. //
  108. // Purpose:
  109. // This is the work horse routine which calls OLE apis.
  110. // The profile is done by creating moniker then calling OleCreateLink on moniker.
  111. //
  112. // Parameters:
  113. //
  114. //
  115. // Return Value:
  116. //
  117. // None
  118. //
  119. // Functions called:
  120. // CallOleCreate defined below
  121. //
  122. //
  123. // Comments:
  124. // Need to add more Server types including In-Proc servers.
  125. //
  126. //********************************************************************
  127. SCODE CIOLTest::Run ()
  128. {
  129. CStopWatch sw;
  130. BOOL fRet;
  131. TCHAR szTemp[MAX_PATH];
  132. OLECHAR szSr2FileName[MAX_PATH];
  133. OLECHAR szOutlFileName[MAX_PATH];
  134. GetCurrentDirectory (MAX_PATH, szTemp);
  135. swprintf(szSr2FileName,
  136. #ifdef UNICODE
  137. L"%s\\foo.sr2",
  138. #else
  139. L"%S\\foo.sr2",
  140. #endif
  141. szTemp);
  142. swprintf(szOutlFileName,
  143. #ifdef UNICODE
  144. L"%s\\foo.oln",
  145. #else
  146. L"%S\\foo.oln",
  147. #endif
  148. szTemp);
  149. fRet = CallOleLinkMethods(szSr2FileName, m_pSite, m_ulIterations,
  150. m_ulOleLinkSr32, L"OTS001", L"OTS002");
  151. fRet = CallOleLinkMethods(szOutlFileName, m_pSite, m_ulIterations,
  152. m_ulOleLinkOutl, L"Name1", L"Name2");
  153. return S_OK;
  154. }
  155. SCODE CIOLTest::Report (CTestOutput &output)
  156. {
  157. //Bail out immediately on STRESS because none of the following variables
  158. //will have sane value
  159. #ifdef STRESS
  160. return S_OK;
  161. #endif
  162. output.WriteString (TEXT("*************************************************\n"));
  163. output.WriteSectionHeader (Name(), TEXT("IOleLink Methods"), *m_pInput);
  164. output.WriteString (TEXT("*************************************************\n"));
  165. output.WriteString (TEXT("\n"));
  166. WriteLinkOutput(output, TEXT(" Sr32test "), m_ulOleLinkSr32, m_ulIterations);
  167. output.WriteString (TEXT("\n"));
  168. output.WriteString (TEXT("\n"));
  169. output.WriteString (TEXT("******************************************\n"));
  170. WriteLinkOutput (output, TEXT(" Outline "), m_ulOleLinkOutl, m_ulIterations);
  171. output.WriteString (TEXT("\n"));
  172. return S_OK;
  173. }
  174. //**********************************************************************
  175. //
  176. // CallOleCreateLink
  177. //
  178. // Purpose:
  179. // Calls OleCreateLink to create the link and then destroys them.
  180. //
  181. //
  182. // Parameters:
  183. //
  184. //
  185. // Return Value:
  186. //
  187. // None
  188. //
  189. // Functions called:
  190. // CreateFileMoniker OLE2 api
  191. // OleCreateLink OLE2 api - Is profiled here
  192. //
  193. //
  194. // Comments:
  195. // Need to add more Server types including In-Proc servers.
  196. //
  197. //********************************************************************
  198. BOOL CallOleLinkMethods(LPCOLESTR lpFileName, CSimpleSite * pSite[],
  199. ULONG ulIterations, LinkTimes IOLTime[], LPCOLESTR lpNm1, LPCOLESTR lpNm2)
  200. {
  201. CStopWatch sw;
  202. HRESULT hres;
  203. ULONG iIter;
  204. LPMONIKER pmk = NULL;
  205. BOOL retVal = FALSE;
  206. #ifdef STRESS
  207. LPOLELINK pLink[STRESSCOUNT] = { NULL };
  208. #else
  209. LPOLELINK pLink[TEST_MAX_ITERATIONS] = { NULL };
  210. #endif
  211. //
  212. //Create the Links and also cache link pointer for rest of the tests
  213. //this pointer is reqd for all the tests later
  214. //
  215. for ( iIter=0; iIter<ulIterations; iIter++)
  216. {
  217. HEAPVALIDATE() ;
  218. if (!pSite[iIter])
  219. goto error;
  220. hres = OleCreateLinkToFile(lpFileName,
  221. IID_IOleObject,
  222. OLERENDER_DRAW,
  223. NULL,
  224. &pSite[iIter]->m_OleClientSite,
  225. pSite[iIter]->m_lpObjStorage,
  226. (VOID FAR* FAR*)&pSite[iIter]->m_lpOleObject
  227. );
  228. if (hres != NOERROR)
  229. goto error;
  230. //Cache IOleLink pointer for rest of the tests that follow below
  231. hres = pSite[iIter]->m_lpOleObject->QueryInterface(IID_IOleLink, (LPVOID FAR*)&pLink[iIter]);
  232. if (hres != NOERROR)
  233. goto error;
  234. }
  235. //
  236. //Run those tests which deal with simple running
  237. //
  238. CallOleLinkRunMethods(IOLTime, pLink, ulIterations);
  239. //
  240. //Call those tests that deal with SourceDisplayName
  241. //
  242. CallOleLinkDisplayName(IOLTime, pLink, lpFileName,
  243. lpNm1, lpNm2, ulIterations);
  244. retVal = TRUE;
  245. error:
  246. if (hres != NOERROR)
  247. Log (TEXT("Routine CallOleCreateLink failed with hres = "), hres);
  248. //CleanUp before going to Next
  249. for (iIter=0; iIter<ulIterations; iIter++)
  250. {
  251. // Unload the object and release the Ole Object
  252. if (pLink[iIter])
  253. pLink[iIter]->Release();
  254. if (pSite[iIter])
  255. pSite[iIter]->UnloadOleObject();
  256. }
  257. return retVal;
  258. }
  259. BOOL CallOleLinkRunMethods(LinkTimes IOLTime[], LPOLELINK pLink[], ULONG ulIterations)
  260. {
  261. HRESULT hres;
  262. CStopWatch sw;
  263. ULONG iIter;
  264. BOOL retVal = FALSE;
  265. LPBINDCTX pBindCtx = NULL;
  266. //
  267. //1. get the first estimates using NULL BindCtx
  268. //
  269. for ( iIter=0; iIter< ulIterations; iIter++)
  270. {
  271. sw.Reset();
  272. hres = pLink[iIter]->BindToSource(NULL /* !BIND_EVEN_IF_CLASSDIF */,
  273. NULL /*Bind Ctx*/);
  274. GetTimerVal(IOLTime[iIter].ulBindToSourceNull);
  275. LOGRESULTS (TEXT("IOL:BindToSource "), hres);
  276. } //End Bind To Source with Null BindCtx
  277. //Unbind links to start next estimates. Which also BindToSource with Non
  278. //NULL BindCtx
  279. for ( iIter=0; iIter< ulIterations; iIter++)
  280. {
  281. hres = pLink[iIter]->UnbindSource();
  282. }
  283. //
  284. //2. Following tests are to be done with BindContext that we get here
  285. //
  286. hres = CreateBindCtx(NULL, &pBindCtx);
  287. if (hres != NOERROR)
  288. goto error;
  289. //Now get the Estimates when Binding with same BindContext
  290. //
  291. for ( iIter=0; iIter< ulIterations; iIter++)
  292. {
  293. sw.Reset();
  294. hres = pLink[iIter]->BindToSource(NULL /* !BIND_EVEN_IF_CLASSDIF */,
  295. pBindCtx /*Bind Ctx*/);
  296. GetTimerVal(IOLTime[iIter].ulBindToSourceBindCtx);
  297. LOGRESULTS (TEXT("IOL:BindToSource "), hres);
  298. } //End Bind To Source with BindCtx
  299. //
  300. //3. Get Estimates for IOL:BindIfRunning
  301. //
  302. for ( iIter=0; iIter<ulIterations; iIter++)
  303. {
  304. sw.Reset();
  305. hres = pLink[iIter]->BindIfRunning();
  306. GetTimerVal(IOLTime[iIter].ulBindIfRunning);
  307. LOGRESULTS (TEXT("IOL:BindIfRunning "), hres);
  308. } //End BindIfRunning, when actually running.
  309. //
  310. //4. Get Estimates for IOL:UnbindSource
  311. //
  312. for ( iIter=0; iIter<ulIterations; iIter++)
  313. {
  314. sw.Reset();
  315. hres = pLink[iIter]->UnbindSource();
  316. GetTimerVal(IOLTime[iIter].ulUnbindSource);
  317. LOGRESULTS (TEXT("IOL:UnbindSource "), hres);
  318. sw.Reset();
  319. hres = pLink[iIter]->UnbindSource();
  320. GetTimerVal(IOLTime[iIter].ulUnbindSource2);
  321. LOGRESULTS (TEXT("IOL:UnbindSource2 "), hres);
  322. }
  323. //
  324. //5. Get Estimates for IOL:BindIfRunning
  325. //
  326. for ( iIter=0; iIter<ulIterations; iIter++)
  327. {
  328. sw.Reset();
  329. hres = pLink[iIter]->BindIfRunning();
  330. GetTimerVal(IOLTime[iIter].ulBindIfRunning2);
  331. LOGRESULTS (TEXT("IOL:BindIfRunning2 "), hres);
  332. } //End BindIfRunning, when not running.
  333. //
  334. //6. Get Estimates for IOL:UnbindSource
  335. //
  336. for ( iIter=0; iIter<ulIterations; iIter++)
  337. {
  338. sw.Reset();
  339. hres = pLink[iIter]->UnbindSource();
  340. GetTimerVal(IOLTime[iIter].ulUnbindSource3);
  341. LOGRESULTS (TEXT("IOL:UnbindSource3 "), hres);
  342. }
  343. retVal = TRUE;
  344. error:
  345. if (pBindCtx)
  346. pBindCtx->Release();
  347. return hres;
  348. }
  349. //**********************************************************************
  350. //
  351. // CallOleLinkDisplayName
  352. //
  353. // Purpose:
  354. // Calls
  355. //
  356. //
  357. // Parameters:
  358. //
  359. //
  360. // Return Value:
  361. //
  362. // None
  363. //
  364. // Functions called:
  365. // OleLoad OLE2 api
  366. // OleSave OLE2 api
  367. //
  368. //
  369. // Comments:
  370. //
  371. //
  372. //********************************************************************
  373. BOOL CallOleLinkDisplayName(LinkTimes IOLTime[], LPOLELINK pLink[],
  374. LPCOLESTR lpFileName, LPCOLESTR lpNm1,
  375. LPCOLESTR lpNm2, ULONG ulIterations)
  376. {
  377. CStopWatch sw;
  378. HRESULT hres;
  379. HRESULT hres2;
  380. ULONG iIter;
  381. BOOL retVal = FALSE;
  382. OLECHAR szMkName1[256];
  383. OLECHAR szMkName2[256];
  384. LPBINDCTX pBindCtx = NULL;
  385. //
  386. //Set the display name to something known and then call IOL:SetDisplayName
  387. //Then update the link so that rest of its info is now updated by OLE.
  388. //
  389. // This code used to grab the moniker from the link, compose with an item
  390. // moniker and then the displayname from the composite moniker. This
  391. // works, although it's rather convoluted, the first time but then the
  392. // code would end up doing it a second time and the first item moniker
  393. // name would still be on the end and it would fail. Just creating the
  394. // new display name ourselves seems much easier anyway.
  395. //
  396. //First get the Moniker Name by following routine
  397. //hres = GetLinkCompositeName(pLink[0], lpNm1, &lpMkName1);
  398. //if (hres != NOERROR)
  399. // goto error;
  400. swprintf(szMkName1, L"%s!%s", lpFileName, lpNm1);
  401. for (iIter=0; iIter<ulIterations; iIter++)
  402. {
  403. sw.Read();
  404. hres = pLink[iIter]->SetSourceDisplayName(szMkName1);
  405. hres2 = pLink[iIter]->Update(NULL);
  406. GetTimerVal(IOLTime[iIter].ulUpdateNull);
  407. LOGRESULTS (TEXT("IOL:SetSourceDisplayName "), hres);
  408. LOGRESULTS (TEXT("IOL:Update "), hres2);
  409. } //End SetSourceDisplayName and Update
  410. //
  411. //Repeate the iteration when we have BindContext available. Check the
  412. //results.
  413. //
  414. //hres = GetLinkCompositeName(pLink[0], lpNm2, &lpMkName2);
  415. //if (hres != NOERROR)
  416. // goto error;
  417. swprintf(szMkName2, L"%s!%s", lpFileName, lpNm2);
  418. hres = CreateBindCtx(NULL, &pBindCtx);
  419. if (hres != NOERROR)
  420. goto error;
  421. for (iIter=0; iIter<ulIterations; iIter++)
  422. {
  423. sw.Read();
  424. hres = pLink[iIter]->SetSourceDisplayName(szMkName2);
  425. hres2 = pLink[iIter]->Update(pBindCtx);
  426. GetTimerVal(IOLTime[iIter].ulUpdateBindCtx);
  427. LOGRESULTS (TEXT("IOL:SetSourceDisplayName "), hres);
  428. LOGRESULTS (TEXT("IOL:Update "), hres2);
  429. } //End SetSourceDisplayName and Update
  430. retVal = TRUE;
  431. error:
  432. if (pBindCtx)
  433. pBindCtx->Release();
  434. return retVal;
  435. }
  436. HRESULT GetLinkCompositeName(LPOLELINK lpLink, LPCOLESTR lpItem, LPOLESTR FAR* lpComposeName)
  437. {
  438. HRESULT hres;
  439. LPMONIKER lpLinkMon = NULL;
  440. LPMONIKER lpItemMk = NULL;
  441. LPMONIKER lpCompose = NULL;
  442. //SInce NULL BindContext not allowed any more
  443. LPBINDCTX pBindCtx = NULL;
  444. //Get the source moniker of the link
  445. hres = lpLink->GetSourceMoniker(&lpLinkMon);
  446. if (hres != NOERROR)
  447. goto error;
  448. //Create item moniker from String Item
  449. hres = CreateItemMoniker(L"!", lpItem, &lpItemMk);
  450. if (hres != NOERROR)
  451. goto error;
  452. //Ask moniker to compose itself with another one in the end to get Composite
  453. //moniker.
  454. hres = lpLinkMon->ComposeWith(lpItemMk, FALSE, &lpCompose);
  455. if (hres != NOERROR)
  456. goto error;
  457. hres = CreateBindCtx(NULL, &pBindCtx);
  458. if (hres != NOERROR)
  459. goto error;
  460. //Get the display Name of the moniker
  461. hres = lpCompose->GetDisplayName(pBindCtx /*BindCtx*/, NULL /*pmkToLeft*/,
  462. lpComposeName);
  463. if (hres != NOERROR)
  464. goto error;
  465. error:
  466. if (lpLinkMon)
  467. lpLinkMon->Release();
  468. if (lpItemMk)
  469. lpItemMk->Release();
  470. if (lpCompose)
  471. lpCompose->Release();
  472. if (pBindCtx)
  473. pBindCtx->Release();
  474. return hres;
  475. }
  476. void WriteLinkOutput(CTestOutput &output, LPTSTR lpstr, LinkTimes *lnkTimes, ULONG ulIterations)
  477. {
  478. UINT iIter;
  479. output.WriteString (TEXT("Name"));
  480. output.WriteString (lpszTab);
  481. output.WriteString (TEXT("BindToSource (NULL)"));
  482. output.WriteString (lpszTab);
  483. output.WriteString (TEXT("BindToSource"));
  484. output.WriteString (lpszTab);
  485. output.WriteString (TEXT("BindIfRunning"));
  486. output.WriteString (lpszTab);
  487. output.WriteString (TEXT("UnBindSource"));
  488. output.WriteString (lpszTab);
  489. output.WriteString (TEXT("UnBindSource2"));
  490. output.WriteString (lpszTab);
  491. output.WriteString (TEXT("BindIfRunning2"));
  492. output.WriteString (lpszTab);
  493. output.WriteString (TEXT("UnBindSource3"));
  494. output.WriteString (lpszTab);
  495. output.WriteString (TEXT("Update(NULL)"));
  496. output.WriteString (lpszTab);
  497. output.WriteString (TEXT("Update"));
  498. output.WriteString (TEXT("\n"));
  499. for (iIter = 0; iIter < ulIterations; iIter++)
  500. {
  501. output.WriteString (lpstr);
  502. output.WriteLong (lnkTimes[iIter].ulBindToSourceNull);
  503. output.WriteString (lpszTab);
  504. output.WriteString (lpszTab);
  505. output.WriteLong (lnkTimes[iIter].ulBindToSourceBindCtx);
  506. output.WriteString (lpszTab);
  507. output.WriteString (lpszTab);
  508. output.WriteLong (lnkTimes[iIter].ulBindIfRunning);
  509. output.WriteString (lpszTab);
  510. output.WriteString (lpszTab);
  511. output.WriteLong (lnkTimes[iIter].ulUnbindSource);
  512. output.WriteString (lpszTab);
  513. output.WriteString (lpszTab);
  514. output.WriteLong (lnkTimes[iIter].ulUnbindSource2);
  515. output.WriteString (lpszTab);
  516. output.WriteString (lpszTab);
  517. output.WriteLong (lnkTimes[iIter].ulBindIfRunning2);
  518. output.WriteString (lpszTab);
  519. output.WriteString (lpszTab);
  520. output.WriteLong (lnkTimes[iIter].ulUnbindSource3);
  521. output.WriteString (lpszTab);
  522. output.WriteString (lpszTab);
  523. output.WriteLong (lnkTimes[iIter].ulUpdateNull);
  524. output.WriteString (lpszTab);
  525. output.WriteString (lpszTab);
  526. output.WriteLong (lnkTimes[iIter].ulUpdateBindCtx);
  527. output.WriteString (TEXT("\n"));
  528. }
  529. }