wiTest.cpp 151 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685
  1. #include <wil/result.h>
  2. #include <wil/resource.h>
  3. #include <wil/win32_helpers.h>
  4. #include <wil/filesystem.h>
  5. #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
  6. #include <wil/wrl.h>
  7. #endif
  8. #include <wil/com.h>
  9. #ifdef WIL_ENABLE_EXCEPTIONS
  10. #include <memory>
  11. #include <set>
  12. #include <thread>
  13. #include <unordered_set>
  14. #endif
  15. // Do not include most headers until after the WIL headers to ensure that we're not inadvertently adding any unnecessary
  16. // dependencies to STL, WRL, or indirectly retrieved headers
  17. #ifndef __cplusplus_winrt
  18. #include <windows.foundation.collections.h>
  19. #include <windows.foundation.h>
  20. #endif
  21. // Include Resource.h a second time after including other headers
  22. #include <wil/resource.h>
  23. #include "common.h"
  24. #include "MallocSpy.h"
  25. #include "test_objects.h"
  26. #pragma warning(push)
  27. #pragma warning(disable: 4702) // Unreachable code
  28. TEST_CASE("WindowsInternalTests::CommonHelpers", "[resource]")
  29. {
  30. {
  31. wil::unique_handle spHandle;
  32. REQUIRE(spHandle == nullptr);
  33. REQUIRE(nullptr == spHandle);
  34. REQUIRE_FALSE(spHandle != nullptr);
  35. REQUIRE_FALSE(nullptr != spHandle);
  36. //equivalence check will static_assert because spMutex does not allow pointer access
  37. wil::mutex_release_scope_exit spMutex;
  38. //REQUIRE(spMutex == nullptr);
  39. //REQUIRE(nullptr == spMutex);
  40. //equivalence check will static_assert because spFile does not use nullptr_t as a invalid value
  41. wil::unique_hfile spFile;
  42. //REQUIRE(spFile == nullptr);
  43. }
  44. #ifdef __WIL_WINBASE_STL
  45. {
  46. wil::shared_handle spHandle;
  47. REQUIRE(spHandle == nullptr);
  48. REQUIRE(nullptr == spHandle);
  49. REQUIRE_FALSE(spHandle != nullptr);
  50. REQUIRE_FALSE(nullptr != spHandle);
  51. }
  52. #endif
  53. }
  54. TEST_CASE("WindowsInternalTests::AssertMacros", "[result_macros]")
  55. {
  56. //WI_ASSERT macros are all no-ops if in retail
  57. #ifndef RESULT_DEBUG
  58. WI_ASSERT(false);
  59. WI_ASSERT_MSG(false, "WI_ASSERT_MSG");
  60. WI_ASSERT_NOASSUME(false);
  61. WI_ASSERT_MSG_NOASSUME(false, "WI_ASSERT_MSG_NOASSUME");
  62. WI_VERIFY(false);
  63. WI_VERIFY_MSG(false, "WI_VERIFY_MSG");
  64. #endif
  65. WI_ASSERT(true);
  66. WI_ASSERT_MSG(true, "WI_ASSERT_MSG");
  67. WI_ASSERT_NOASSUME(true);
  68. WI_ASSERT_MSG_NOASSUME(true, "WI_ASSERT_MSG_NOASSUME");
  69. WI_VERIFY(true);
  70. WI_VERIFY_MSG(true, "WI_VERIFY_MSG");
  71. }
  72. void __stdcall EmptyResultMacrosLoggingCallback(wil::FailureInfo*, PWSTR, size_t) WI_NOEXCEPT
  73. {
  74. }
  75. #ifdef WIL_ENABLE_EXCEPTIONS
  76. // Test Result Macros
  77. void TestErrorCallbacks()
  78. {
  79. {
  80. size_t callbackCount = 0;
  81. auto monitor = wil::ThreadFailureCallback([&](wil::FailureInfo const &failure) -> bool
  82. {
  83. REQUIRE(failure.hr == E_ACCESSDENIED);
  84. callbackCount++;
  85. return false;
  86. });
  87. constexpr size_t depthCount = 10;
  88. for (size_t index = 0; index < depthCount; index++)
  89. {
  90. LOG_HR(E_ACCESSDENIED);
  91. }
  92. REQUIRE(callbackCount == depthCount);
  93. }
  94. {
  95. wil::ThreadFailureCache cache;
  96. LOG_HR(E_ACCESSDENIED);
  97. REQUIRE(cache.GetFailure() != nullptr);
  98. REQUIRE(cache.GetFailure()->hr == E_ACCESSDENIED);
  99. wil::ThreadFailureCache cacheNested;
  100. LOG_HR(E_FAIL); unsigned long errorLine = __LINE__;
  101. LOG_HR(E_FAIL);
  102. LOG_HR(E_FAIL);
  103. REQUIRE(cache.GetFailure()->hr == E_FAIL);
  104. REQUIRE(cache.GetFailure()->uLineNumber == errorLine);
  105. REQUIRE(cacheNested.GetFailure()->hr == E_FAIL);
  106. REQUIRE(cacheNested.GetFailure()->uLineNumber == errorLine);
  107. }
  108. }
  109. DWORD WINAPI ErrorCallbackThreadTest(_In_ LPVOID lpParameter)
  110. {
  111. try
  112. {
  113. HANDLE hEvent = reinterpret_cast<HANDLE>(lpParameter);
  114. for (size_t stress = 0; stress < 200; stress++)
  115. {
  116. Sleep(1); // allow the threadpool to saturate the thread count...
  117. TestErrorCallbacks();
  118. }
  119. THROW_IF_WIN32_BOOL_FALSE(::SetEvent(hEvent));
  120. }
  121. catch (...)
  122. {
  123. FAIL();
  124. }
  125. return 1;
  126. }
  127. void StressErrorCallbacks()
  128. {
  129. auto restore = witest::AssignTemporaryValue(&wil::g_fResultOutputDebugString, false);
  130. constexpr size_t threadCount = 20;
  131. wil::unique_event eventArray[threadCount];
  132. for (size_t index = 0; index < threadCount; index++)
  133. {
  134. eventArray[index].create();
  135. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  136. THROW_IF_WIN32_BOOL_FALSE(::QueueUserWorkItem(ErrorCallbackThreadTest, eventArray[index].get(), 0));
  137. #else
  138. ErrorCallbackThreadTest(eventArray[index].get());
  139. #endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
  140. }
  141. for (size_t index = 0; index < threadCount; index++)
  142. {
  143. eventArray[index].wait();
  144. }
  145. }
  146. TEST_CASE("WindowsInternalTests::ResultMacrosStress", "[LocalOnly][result_macros][stress]")
  147. {
  148. auto restore = witest::AssignTemporaryValue(&wil::g_pfnResultLoggingCallback, EmptyResultMacrosLoggingCallback);
  149. StressErrorCallbacks();
  150. }
  151. #endif
  152. #define E_AD HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)
  153. void SetAD()
  154. {
  155. ::SetLastError(ERROR_ACCESS_DENIED);
  156. }
  157. class AlternateAccessDeniedException
  158. {
  159. };
  160. #ifdef WIL_ENABLE_EXCEPTIONS
  161. class DerivedAccessDeniedException : public wil::ResultException
  162. {
  163. public:
  164. DerivedAccessDeniedException() : ResultException(E_AD) {}
  165. };
  166. HRESULT __stdcall TestResultCaughtFromException() WI_NOEXCEPT
  167. {
  168. try
  169. {
  170. throw;
  171. }
  172. catch (AlternateAccessDeniedException)
  173. {
  174. return E_AD;
  175. }
  176. catch (...)
  177. {
  178. }
  179. return S_OK;
  180. }
  181. #endif
  182. HANDLE hValid = reinterpret_cast<HANDLE>(1);
  183. HANDLE& hValidRef() { return hValid; }
  184. HANDLE hNull = NULL;
  185. HANDLE hInvalid = INVALID_HANDLE_VALUE;
  186. void* pValid = reinterpret_cast<void *>(1);
  187. void*& pValidRef() { return pValid; }
  188. void* pNull = nullptr;
  189. void*& pNullRef() { return pNull; }
  190. bool fTrue = true;
  191. bool& fTrueRef() { return fTrue; }
  192. bool fFalse = false;
  193. bool& fFalseRef() { return fFalse; }
  194. BOOL fTRUE = TRUE;
  195. BOOL& fTRUERef() { return fTRUE; }
  196. BOOL fFALSE = FALSE;
  197. DWORD errSuccess = ERROR_SUCCESS;
  198. DWORD& errSuccessRef() { return errSuccess; }
  199. HRESULT hrOK = S_OK;
  200. HRESULT& hrOKRef() { return hrOK; }
  201. HRESULT hrFAIL = E_FAIL;
  202. HRESULT& hrFAILRef() { return hrFAIL; }
  203. const HRESULT E_hrOutOfPaper = HRESULT_FROM_WIN32(ERROR_OUT_OF_PAPER);
  204. NTSTATUS ntOK = STATUS_SUCCESS;
  205. NTSTATUS& ntOKRef() { return ntOK; }
  206. NTSTATUS ntFAIL = STATUS_NO_MEMORY;
  207. NTSTATUS& ntFAILRef() { return ntFAIL; }
  208. const HRESULT S_hrNtOkay = wil::details::NtStatusToHr(STATUS_SUCCESS);
  209. const HRESULT E_hrNtAssertionFailure = wil::details::NtStatusToHr(STATUS_ASSERTION_FAILURE);
  210. wil::StoredFailureInfo g_log;
  211. void __stdcall ResultMacrosLoggingCallback(wil::FailureInfo *pFailure, PWSTR, size_t) WI_NOEXCEPT
  212. {
  213. g_log = *pFailure;
  214. }
  215. enum class EType
  216. {
  217. None = 0x00,
  218. Expected = 0x02,
  219. Msg = 0x04,
  220. FailFast = 0x08, // overall fail fast (throw exception on successful result code, for example)
  221. FailFastMacro = 0x10, // explicit use of fast fail fast (FAIL_FAST_IF...)
  222. NoContext = 0x20 // file and line info can be wrong (throw does not happen in context to code)
  223. };
  224. DEFINE_ENUM_FLAG_OPERATORS(EType);
  225. template <typename TLambda>
  226. bool VerifyResult(unsigned int lineNumber, EType type, HRESULT hr, TLambda&& lambda)
  227. {
  228. bool succeeded = true;
  229. #ifdef WIL_ENABLE_EXCEPTIONS
  230. try
  231. {
  232. #endif
  233. HRESULT lambdaResult = E_FAIL;
  234. bool didFailFast = true;
  235. {
  236. didFailFast = witest::DoesCodeCrash([&]()
  237. {
  238. lambdaResult = lambda();
  239. });
  240. }
  241. if (WI_IsFlagSet(type, EType::FailFast))
  242. {
  243. REQUIRE(didFailFast);
  244. }
  245. else
  246. {
  247. if (WI_IsFlagClear(type, EType::Expected))
  248. {
  249. if (SUCCEEDED(hr))
  250. {
  251. REQUIRE(hr == lambdaResult);
  252. REQUIRE(lineNumber != g_log.GetFailureInfo().uLineNumber);
  253. REQUIRE(!didFailFast);
  254. }
  255. else
  256. {
  257. REQUIRE((WI_IsFlagSet(type, EType::NoContext) || (g_log.GetFailureInfo().uLineNumber == lineNumber)));
  258. REQUIRE(g_log.GetFailureInfo().hr == hr);
  259. REQUIRE((WI_IsFlagClear(type, EType::Msg) || (nullptr != wcsstr(g_log.GetFailureInfo().pszMessage, L"msg"))));
  260. REQUIRE((WI_IsFlagClear(type, EType::FailFastMacro) || (didFailFast)));
  261. REQUIRE((WI_IsFlagSet(type, EType::FailFastMacro) || (!didFailFast)));
  262. }
  263. }
  264. }
  265. #ifdef WIL_ENABLE_EXCEPTIONS
  266. }
  267. catch (...)
  268. {
  269. succeeded = false;
  270. }
  271. #endif
  272. // Ensure we come out clean...
  273. ::SetLastError(ERROR_SUCCESS);
  274. return succeeded;
  275. }
  276. #ifdef WIL_ENABLE_EXCEPTIONS
  277. template <typename TLambda>
  278. HRESULT TranslateException(TLambda&& lambda)
  279. {
  280. try
  281. {
  282. lambda();
  283. }
  284. catch (wil::ResultException &re)
  285. {
  286. return re.GetErrorCode();
  287. }
  288. #ifdef __cplusplus_winrt
  289. catch (Platform::Exception ^pe)
  290. {
  291. return wil::details::GetErrorCode(pe);
  292. }
  293. #endif
  294. catch (...)
  295. {
  296. FAIL();
  297. }
  298. return S_OK;
  299. }
  300. #endif
  301. #define REQUIRE_RETURNS(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::None, hr, lambda))
  302. #define REQUIRE_RETURNS_MSG(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::Msg, hr, lambda))
  303. #define REQUIRE_RETURNS_EXPECTED(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::Expected, hr, lambda))
  304. #ifdef WIL_ENABLE_EXCEPTIONS
  305. #define REQUIRE_THROWS_RESULT(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::None, hr, [&] { return TranslateException(lambda); }))
  306. #define REQUIRE_THROWS_MSG(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::Msg, hr, [&] { return TranslateException(lambda); }))
  307. #else
  308. #define REQUIRE_THROWS_RESULT(hr, lambda)
  309. #define REQUIRE_THROWS_MSG(hr, lambda)
  310. #endif
  311. #define REQUIRE_LOG(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::None, hr, [&] { auto fn = (lambda); fn(); return hr; }))
  312. #define REQUIRE_LOG_MSG(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::Msg, hr, [&] { auto fn = (lambda); fn(); return hr; }))
  313. #define REQUIRE_FAILFAST(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::FailFastMacro, hr, [&] { auto fn = (lambda); fn(); return hr; }))
  314. #define REQUIRE_FAILFAST_MSG(hr, lambda) REQUIRE(VerifyResult(__LINE__, EType::FailFastMacro | EType::Msg, hr, [&] { auto fn = (lambda); fn(); return hr; }))
  315. #define REQUIRE_FAILFAST_UNSPECIFIED(lambda) REQUIRE(VerifyResult(__LINE__, EType::FailFast, S_OK, [&] { auto fn = (lambda); fn(); return S_OK; }))
  316. TEST_CASE("WindowsInternalTests::ResultMacros", "[result_macros]")
  317. {
  318. auto restoreLoggingCallback = witest::AssignTemporaryValue(&wil::g_pfnResultLoggingCallback, ResultMacrosLoggingCallback);
  319. #ifdef WIL_ENABLE_EXCEPTIONS
  320. auto restoreExceptionCallback = witest::AssignTemporaryValue(&wil::g_pfnResultFromCaughtException, TestResultCaughtFromException);
  321. #endif
  322. REQUIRE_RETURNS(S_OK, [] { RETURN_HR(MDEC(hrOKRef())); });
  323. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__); });
  324. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR(MDEC(hrOKRef())); });
  325. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__); });
  326. REQUIRE_RETURNS(E_FAIL, [] { RETURN_HR(E_FAIL); });
  327. REQUIRE_RETURNS_MSG(E_FAIL, [] { RETURN_HR_MSG(E_FAIL, "msg: %d", __LINE__); });
  328. REQUIRE_THROWS_RESULT(E_FAIL, [] { THROW_HR(E_FAIL); });
  329. REQUIRE_THROWS_MSG(E_FAIL, [] { THROW_HR_MSG(E_FAIL, "msg: %d", __LINE__); });
  330. REQUIRE_LOG(E_FAIL, [] { LOG_HR(E_FAIL); });
  331. REQUIRE_LOG_MSG(E_FAIL, [] { LOG_HR_MSG(E_FAIL, "msg: %d", __LINE__); });
  332. REQUIRE_FAILFAST(E_FAIL, [] { FAIL_FAST_HR(E_FAIL); });
  333. REQUIRE_FAILFAST_MSG(E_FAIL, [] { FAIL_FAST_HR_MSG(E_FAIL, "msg: %d", __LINE__); });
  334. REQUIRE_FAILFAST_UNSPECIFIED([] { ::SetLastError(0); FAIL_FAST_LAST_ERROR(); });
  335. REQUIRE_FAILFAST_UNSPECIFIED([] { ::SetLastError(0); FAIL_FAST_LAST_ERROR_MSG("msg: %d", __LINE__); });
  336. REQUIRE_RETURNS(E_AD, [] { SetAD(); RETURN_LAST_ERROR(); });
  337. REQUIRE_RETURNS_MSG(E_AD, [] { SetAD(); RETURN_LAST_ERROR_MSG("msg: %d", __LINE__); });
  338. REQUIRE_THROWS_RESULT(E_AD, [] { SetAD(); THROW_LAST_ERROR(); });
  339. REQUIRE_THROWS_MSG(E_AD, [] { SetAD(); THROW_LAST_ERROR_MSG("msg: %d", __LINE__); });
  340. REQUIRE_LOG(E_AD, [] { SetAD(); LOG_LAST_ERROR(); });
  341. REQUIRE_LOG_MSG(E_AD, [] { SetAD(); LOG_LAST_ERROR_MSG("msg: %d", __LINE__); });
  342. REQUIRE_FAILFAST(E_AD, [] { SetAD(); FAIL_FAST_LAST_ERROR(); });
  343. REQUIRE_FAILFAST_MSG(E_AD, [] { SetAD(); FAIL_FAST_LAST_ERROR_MSG("msg: %d", __LINE__); });
  344. REQUIRE_RETURNS(S_OK, [] { RETURN_WIN32(MDEC(errSuccessRef())); });
  345. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_WIN32_MSG(MDEC(errSuccessRef()), "msg: %d", __LINE__); });
  346. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_WIN32(MDEC(errSuccessRef())); });
  347. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_WIN32_MSG(MDEC(errSuccessRef()), "msg: %d", __LINE__); });
  348. REQUIRE_RETURNS(E_AD, [] { RETURN_WIN32(ERROR_ACCESS_DENIED); });
  349. REQUIRE_RETURNS_MSG(E_AD, [] { RETURN_WIN32_MSG(ERROR_ACCESS_DENIED, "msg: %d", __LINE__); });
  350. REQUIRE_THROWS_RESULT(E_AD, [] { THROW_WIN32(ERROR_ACCESS_DENIED); });
  351. REQUIRE_THROWS_MSG(E_AD, [] { THROW_WIN32_MSG(ERROR_ACCESS_DENIED, "msg: %d", __LINE__); });
  352. REQUIRE_LOG(E_AD, [] { LOG_WIN32(ERROR_ACCESS_DENIED); });
  353. REQUIRE_LOG_MSG(E_AD, [] { LOG_WIN32_MSG(ERROR_ACCESS_DENIED, "msg: %d", __LINE__); });
  354. REQUIRE_FAILFAST(E_AD, [] { FAIL_FAST_WIN32(ERROR_ACCESS_DENIED); });
  355. REQUIRE_FAILFAST_MSG(E_AD, [] { FAIL_FAST_WIN32_MSG(ERROR_ACCESS_DENIED, "msg: %d", __LINE__); });
  356. REQUIRE_RETURNS(S_OK, [] { RETURN_IF_FAILED(MDEC(hrOKRef())); return S_OK; });
  357. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_IF_FAILED_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__); return S_OK; });
  358. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_IF_FAILED_EXPECTED(MDEC(hrOKRef())); return S_OK; });
  359. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(S_OK == THROW_IF_FAILED(MDEC(hrOKRef()))); });
  360. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(S_OK == THROW_IF_FAILED_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__)); });
  361. REQUIRE_LOG(S_OK, [] { REQUIRE(S_OK == LOG_IF_FAILED(MDEC(hrOKRef()))); });
  362. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(S_OK == LOG_IF_FAILED_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__)); });
  363. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(S_OK == FAIL_FAST_IF_FAILED(MDEC(hrOKRef()))); });
  364. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(S_OK == FAIL_FAST_IF_FAILED_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__)); });
  365. REQUIRE_RETURNS(E_FAIL, [] { RETURN_IF_FAILED(E_FAIL); return S_OK; });
  366. REQUIRE_RETURNS_MSG(E_FAIL, [] { RETURN_IF_FAILED_MSG(E_FAIL, "msg: %d", __LINE__); return S_OK; });
  367. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { RETURN_IF_FAILED_EXPECTED(E_FAIL); return S_OK; });
  368. REQUIRE_THROWS_RESULT(E_FAIL, [] { THROW_IF_FAILED(E_FAIL); });
  369. REQUIRE_THROWS_MSG(E_FAIL, [] { THROW_IF_FAILED_MSG(E_FAIL, "msg: %d", __LINE__); });
  370. REQUIRE_LOG(E_FAIL, [] { REQUIRE(E_FAIL == LOG_IF_FAILED(E_FAIL)); });
  371. REQUIRE_LOG_MSG(E_FAIL, [] { REQUIRE(E_FAIL == LOG_IF_FAILED_MSG(E_FAIL, "msg: %d", __LINE__)); });
  372. REQUIRE_FAILFAST(E_FAIL, [] { FAIL_FAST_IF_FAILED(E_FAIL); });
  373. REQUIRE_FAILFAST_MSG(E_FAIL, [] { FAIL_FAST_IF_FAILED_MSG(E_FAIL, "msg: %d", __LINE__); });
  374. REQUIRE_RETURNS(S_OK, [] { RETURN_IF_WIN32_BOOL_FALSE(MDEC(fTRUERef())); return S_OK; });
  375. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_IF_WIN32_BOOL_FALSE_MSG(MDEC(fTRUERef()), "msg: %d", __LINE__); return S_OK; });
  376. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(MDEC(fTRUERef())); return S_OK; });
  377. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(fTRUE == THROW_IF_WIN32_BOOL_FALSE(MDEC(fTRUERef()))); });
  378. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(fTRUE == THROW_IF_WIN32_BOOL_FALSE_MSG(MDEC(fTRUERef()), "msg: %d", __LINE__)); });
  379. REQUIRE_LOG(S_OK, [] { REQUIRE(fTRUE == LOG_IF_WIN32_BOOL_FALSE(MDEC(fTRUERef()))); });
  380. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(fTRUE == LOG_IF_WIN32_BOOL_FALSE_MSG(MDEC(fTRUERef()), "msg: %d", __LINE__)); });
  381. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(fTRUE == FAIL_FAST_IF_WIN32_BOOL_FALSE(MDEC(fTRUERef()))); });
  382. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(fTRUE == FAIL_FAST_IF_WIN32_BOOL_FALSE_MSG(MDEC(fTRUERef()), "msg: %d", __LINE__)); });
  383. REQUIRE_RETURNS(E_AD, [] { SetAD(); RETURN_IF_WIN32_BOOL_FALSE(fFALSE); return S_OK; });
  384. REQUIRE_RETURNS_MSG(E_AD, [] { SetAD(); RETURN_IF_WIN32_BOOL_FALSE_MSG(fFALSE, "msg: %d", __LINE__); return S_OK; });
  385. REQUIRE_RETURNS_EXPECTED(E_AD, [] { SetAD(); RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(fFALSE); return S_OK; });
  386. REQUIRE_THROWS_RESULT(E_AD, [] { SetAD(); THROW_IF_WIN32_BOOL_FALSE(fFALSE); });
  387. REQUIRE_THROWS_MSG(E_AD, [] { SetAD(); THROW_IF_WIN32_BOOL_FALSE_MSG(fFALSE, "msg: %d", __LINE__); });
  388. REQUIRE_LOG(E_AD, [] { SetAD(); REQUIRE(fFALSE == LOG_IF_WIN32_BOOL_FALSE(fFALSE)); });
  389. REQUIRE_LOG_MSG(E_AD, [] { SetAD(); REQUIRE(fFALSE == LOG_IF_WIN32_BOOL_FALSE_MSG(fFALSE, "msg: %d", __LINE__)); });
  390. REQUIRE_FAILFAST(E_AD, [] { SetAD(); FAIL_FAST_IF_WIN32_BOOL_FALSE(fFALSE); });
  391. REQUIRE_FAILFAST_MSG(E_AD, [] { SetAD(); FAIL_FAST_IF_WIN32_BOOL_FALSE_MSG(fFALSE, "msg: %d", __LINE__); });
  392. REQUIRE_RETURNS(S_OK, [] { RETURN_IF_WIN32_ERROR(MDEC(hrOKRef())); return S_OK; });
  393. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_IF_WIN32_ERROR_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__); return S_OK; });
  394. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_IF_WIN32_ERROR_EXPECTED(MDEC(hrOKRef())); return S_OK; });
  395. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(S_OK == THROW_IF_WIN32_ERROR(MDEC(hrOKRef()))); });
  396. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(S_OK == THROW_IF_WIN32_ERROR_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__)); });
  397. REQUIRE_LOG(S_OK, [] { REQUIRE(S_OK == LOG_IF_WIN32_ERROR(MDEC(hrOKRef()))); });
  398. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(S_OK == LOG_IF_WIN32_ERROR_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__)); });
  399. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(S_OK == FAIL_FAST_IF_WIN32_ERROR(MDEC(hrOKRef()))); });
  400. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(S_OK == FAIL_FAST_IF_WIN32_ERROR_MSG(MDEC(hrOKRef()), "msg: %d", __LINE__)); });
  401. REQUIRE_RETURNS(E_hrOutOfPaper, [] { RETURN_IF_WIN32_ERROR(ERROR_OUT_OF_PAPER); return S_OK; });
  402. REQUIRE_RETURNS_MSG(E_hrOutOfPaper, [] { RETURN_IF_WIN32_ERROR_MSG(ERROR_OUT_OF_PAPER, "msg: %d", __LINE__); return S_OK; });
  403. REQUIRE_RETURNS_EXPECTED(E_hrOutOfPaper, [] { RETURN_IF_WIN32_ERROR_EXPECTED(ERROR_OUT_OF_PAPER); return S_OK; });
  404. REQUIRE_THROWS_RESULT(E_hrOutOfPaper, [] { THROW_IF_WIN32_ERROR(ERROR_OUT_OF_PAPER); });
  405. REQUIRE_THROWS_MSG(E_hrOutOfPaper, [] { THROW_IF_WIN32_ERROR_MSG(ERROR_OUT_OF_PAPER, "msg: %d", __LINE__); });
  406. REQUIRE_LOG(E_hrOutOfPaper, [] { REQUIRE(ERROR_OUT_OF_PAPER == LOG_IF_WIN32_ERROR(ERROR_OUT_OF_PAPER)); });
  407. REQUIRE_LOG_MSG(E_hrOutOfPaper, [] { REQUIRE(ERROR_OUT_OF_PAPER == LOG_IF_WIN32_ERROR_MSG(ERROR_OUT_OF_PAPER, "msg: %d", __LINE__)); });
  408. REQUIRE_FAILFAST(E_hrOutOfPaper, [] { FAIL_FAST_IF_WIN32_ERROR(ERROR_OUT_OF_PAPER); });
  409. REQUIRE_FAILFAST_MSG(E_hrOutOfPaper, [] { FAIL_FAST_IF_WIN32_ERROR_MSG(ERROR_OUT_OF_PAPER, "msg: %d", __LINE__); });
  410. REQUIRE_RETURNS(S_hrNtOkay, [] { RETURN_NTSTATUS(MDEC(ntOKRef())); });
  411. REQUIRE_RETURNS_MSG(S_hrNtOkay, [] { RETURN_NTSTATUS_MSG(MDEC(ntOKRef()), "msg: %d", __LINE__); });
  412. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_NTSTATUS(MDEC(ntOKRef())); });
  413. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_NTSTATUS_MSG(MDEC(ntOKRef()), "msg: %d", __LINE__); });
  414. REQUIRE_RETURNS(E_hrNtAssertionFailure, [] { RETURN_NTSTATUS(STATUS_ASSERTION_FAILURE); });
  415. REQUIRE_RETURNS_MSG(E_hrNtAssertionFailure, [] { RETURN_NTSTATUS_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__); });
  416. REQUIRE_THROWS_RESULT(E_hrNtAssertionFailure, [] { THROW_NTSTATUS(STATUS_ASSERTION_FAILURE); });
  417. REQUIRE_THROWS_MSG(E_hrNtAssertionFailure, [] { THROW_NTSTATUS_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__); });
  418. REQUIRE_LOG(E_hrNtAssertionFailure, [] { LOG_NTSTATUS(STATUS_ASSERTION_FAILURE); });
  419. REQUIRE_LOG_MSG(E_hrNtAssertionFailure, [] { LOG_NTSTATUS_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__); });
  420. REQUIRE_FAILFAST(E_hrNtAssertionFailure, [] { FAIL_FAST_NTSTATUS(STATUS_ASSERTION_FAILURE); });
  421. REQUIRE_FAILFAST_MSG(E_hrNtAssertionFailure, [] { FAIL_FAST_NTSTATUS_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__); });
  422. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_IF_NTSTATUS_FAILED_MSG(MDEC(ntOKRef()), "msg: %d", __LINE__); return S_OK; });
  423. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_IF_NTSTATUS_FAILED_EXPECTED(MDEC(ntOKRef())); return S_OK; });
  424. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(STATUS_WAIT_0 == THROW_IF_NTSTATUS_FAILED(MDEC(ntOKRef()))); });
  425. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(STATUS_WAIT_0 == THROW_IF_NTSTATUS_FAILED_MSG(MDEC(ntOKRef()), "msg: %d", __LINE__)); });
  426. REQUIRE_LOG(S_OK, [] { REQUIRE(STATUS_WAIT_0 == LOG_IF_NTSTATUS_FAILED(MDEC(ntOKRef()))); });
  427. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(STATUS_WAIT_0 == LOG_IF_NTSTATUS_FAILED_MSG(MDEC(ntOKRef()), "msg: %d", __LINE__)); });
  428. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(STATUS_WAIT_0 == FAIL_FAST_IF_NTSTATUS_FAILED(MDEC(ntOKRef()))); });
  429. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(STATUS_WAIT_0 == FAIL_FAST_IF_NTSTATUS_FAILED_MSG(MDEC(ntOKRef()), "msg: %d", __LINE__)); });
  430. REQUIRE_RETURNS(E_hrNtAssertionFailure, [] { RETURN_IF_NTSTATUS_FAILED(STATUS_ASSERTION_FAILURE); return S_OK; });
  431. REQUIRE_RETURNS_MSG(E_hrNtAssertionFailure, [] { RETURN_IF_NTSTATUS_FAILED_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__); return S_OK; });
  432. REQUIRE_RETURNS_EXPECTED(E_hrNtAssertionFailure, [] { RETURN_IF_NTSTATUS_FAILED_EXPECTED(STATUS_ASSERTION_FAILURE); return S_OK; });
  433. REQUIRE_THROWS_RESULT(E_hrNtAssertionFailure, [] { THROW_IF_NTSTATUS_FAILED(STATUS_ASSERTION_FAILURE); });
  434. REQUIRE_THROWS_MSG(E_hrNtAssertionFailure, [] { THROW_IF_NTSTATUS_FAILED_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__); });
  435. REQUIRE_LOG(E_hrNtAssertionFailure, [] { REQUIRE(STATUS_ASSERTION_FAILURE == static_cast<DWORD>(LOG_IF_NTSTATUS_FAILED(STATUS_ASSERTION_FAILURE))); });
  436. REQUIRE_LOG_MSG(E_hrNtAssertionFailure, [] { REQUIRE(STATUS_ASSERTION_FAILURE == static_cast<DWORD>(LOG_IF_NTSTATUS_FAILED_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__))); });
  437. REQUIRE_FAILFAST(E_hrNtAssertionFailure, [] { FAIL_FAST_IF_NTSTATUS_FAILED(STATUS_ASSERTION_FAILURE); });
  438. REQUIRE_FAILFAST_MSG(E_hrNtAssertionFailure, [] { FAIL_FAST_IF_NTSTATUS_FAILED_MSG(STATUS_ASSERTION_FAILURE, "msg: %d", __LINE__); });
  439. REQUIRE_RETURNS(E_OUTOFMEMORY, [] { RETURN_IF_NTSTATUS_FAILED(STATUS_NO_MEMORY); return S_OK; });
  440. REQUIRE_RETURNS_MSG(E_OUTOFMEMORY, [] { RETURN_IF_NTSTATUS_FAILED_MSG(STATUS_NO_MEMORY, "msg: %d", __LINE__); return S_OK; });
  441. REQUIRE_RETURNS_EXPECTED(E_OUTOFMEMORY, [] { RETURN_IF_NTSTATUS_FAILED_EXPECTED(STATUS_NO_MEMORY); return S_OK; });
  442. REQUIRE_THROWS_RESULT(E_OUTOFMEMORY, [] { THROW_IF_NTSTATUS_FAILED(STATUS_NO_MEMORY); });
  443. REQUIRE_THROWS_MSG(E_OUTOFMEMORY, [] { THROW_IF_NTSTATUS_FAILED_MSG(STATUS_NO_MEMORY, "msg: %d", __LINE__); });
  444. REQUIRE_LOG(E_OUTOFMEMORY, [] { REQUIRE(STATUS_NO_MEMORY == static_cast<DWORD>(LOG_IF_NTSTATUS_FAILED(STATUS_NO_MEMORY))); });
  445. REQUIRE_LOG_MSG(E_OUTOFMEMORY, [] { REQUIRE(STATUS_NO_MEMORY == static_cast<DWORD>(LOG_IF_NTSTATUS_FAILED_MSG(STATUS_NO_MEMORY, "msg: %d", __LINE__))); });
  446. REQUIRE_FAILFAST(E_OUTOFMEMORY, [] { FAIL_FAST_IF_NTSTATUS_FAILED(STATUS_NO_MEMORY); });
  447. REQUIRE_FAILFAST_MSG(E_OUTOFMEMORY, [] { FAIL_FAST_IF_NTSTATUS_FAILED_MSG(STATUS_NO_MEMORY, "msg: %d", __LINE__); });
  448. REQUIRE_RETURNS(S_OK, [] { RETURN_IF_NULL_ALLOC(MDEC(pValidRef())); return S_OK; });
  449. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_IF_NULL_ALLOC_MSG(MDEC(pValidRef()), "msg: %d", __LINE__); return S_OK; });
  450. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_IF_NULL_ALLOC_EXPECTED(MDEC(pValidRef())); return S_OK; });
  451. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(pValid == THROW_IF_NULL_ALLOC(MDEC(pValidRef()))); });
  452. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(pValid == THROW_IF_NULL_ALLOC_MSG(MDEC(pValidRef()), "msg: %d", __LINE__)); });
  453. REQUIRE_LOG(S_OK, [] { REQUIRE(pValid == LOG_IF_NULL_ALLOC(MDEC(pValidRef()))); });
  454. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(pValid == LOG_IF_NULL_ALLOC_MSG(MDEC(pValidRef()), "msg: %d", __LINE__)); });
  455. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(pValid == FAIL_FAST_IF_NULL_ALLOC(MDEC(pValidRef()))); });
  456. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(pValid == FAIL_FAST_IF_NULL_ALLOC_MSG(MDEC(pValidRef()), "msg: %d", __LINE__)); });
  457. REQUIRE_RETURNS(E_OUTOFMEMORY, [] { RETURN_IF_NULL_ALLOC(pNull); return S_OK; });
  458. REQUIRE_RETURNS_MSG(E_OUTOFMEMORY, [] { RETURN_IF_NULL_ALLOC_MSG(pNull, "msg: %d", __LINE__); return S_OK; });
  459. REQUIRE_RETURNS_EXPECTED(E_OUTOFMEMORY, [] { RETURN_IF_NULL_ALLOC_EXPECTED(pNull); return S_OK; });
  460. REQUIRE_THROWS_RESULT(E_OUTOFMEMORY, [] { THROW_IF_NULL_ALLOC(pNull); });
  461. REQUIRE_THROWS_MSG(E_OUTOFMEMORY, [] { THROW_IF_NULL_ALLOC_MSG(pNull, "msg: %d", __LINE__); });
  462. REQUIRE_LOG(E_OUTOFMEMORY, [] { REQUIRE(pNull == LOG_IF_NULL_ALLOC(pNull)); });
  463. REQUIRE_LOG_MSG(E_OUTOFMEMORY, [] { REQUIRE(pNull == LOG_IF_NULL_ALLOC_MSG(pNull, "msg: %d", __LINE__)); });
  464. REQUIRE_FAILFAST(E_OUTOFMEMORY, [] { FAIL_FAST_IF_NULL_ALLOC(pNull); });
  465. REQUIRE_FAILFAST_MSG(E_OUTOFMEMORY, [] { FAIL_FAST_IF_NULL_ALLOC_MSG(pNull, "msg: %d", __LINE__); });
  466. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF(MDEC(S_OK), MDEC(fTrueRef())); return S_OK; });
  467. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_MSG(MDEC(S_OK), MDEC(fTrueRef()), "msg: %d", __LINE__); return S_OK; });
  468. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_EXPECTED(MDEC(S_OK), MDEC(fTrueRef())); return S_OK; });
  469. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR_IF(MDEC(S_OK), MDEC(fTrueRef())); });
  470. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR_IF_MSG(MDEC(S_OK), MDEC(fTrueRef()), "msg: %d", __LINE__); });
  471. REQUIRE_RETURNS(E_FAIL, [] { RETURN_HR_IF(E_FAIL, fTrue); return S_OK; });
  472. REQUIRE_RETURNS_MSG(E_FAIL, [] { RETURN_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__); return S_OK; });
  473. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { RETURN_HR_IF_EXPECTED(E_FAIL, fTrue); return S_OK; });
  474. REQUIRE_THROWS_RESULT(E_FAIL, [] { THROW_HR_IF(E_FAIL, fTrue); });
  475. REQUIRE_THROWS_MSG(E_FAIL, [] { THROW_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__); });
  476. REQUIRE_LOG(E_FAIL, [] { REQUIRE(fTrue == LOG_HR_IF(E_FAIL, fTrue)); });
  477. REQUIRE_LOG_MSG(E_FAIL, [] { REQUIRE(fTrue == LOG_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__)); });
  478. REQUIRE_FAILFAST(E_FAIL, [] { FAIL_FAST_HR_IF(E_FAIL, fTrue); });
  479. REQUIRE_FAILFAST_MSG(E_FAIL, [] { FAIL_FAST_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__); });
  480. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF(MDEC(S_OK), MDEC(fTrueRef())); return S_OK; });
  481. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_MSG(MDEC(S_OK), MDEC(fTrueRef()), "msg: %d", __LINE__); return S_OK; });
  482. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_EXPECTED(MDEC(S_OK), MDEC(fTrueRef())); return S_OK; });
  483. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR_IF(MDEC(S_OK), MDEC(fTrueRef())); });
  484. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR_IF_MSG(MDEC(S_OK), MDEC(fTrueRef()), "msg: %d", __LINE__); });
  485. REQUIRE_RETURNS(E_FAIL, [] { RETURN_HR_IF(E_FAIL, fTrue); return S_OK; });
  486. REQUIRE_RETURNS_MSG(E_FAIL, [] { RETURN_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__); return S_OK; });
  487. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { RETURN_HR_IF_EXPECTED(E_FAIL, fTrue); return S_OK; });
  488. REQUIRE_THROWS_RESULT(E_FAIL, [] { THROW_HR_IF(E_FAIL, fTrue); });
  489. REQUIRE_THROWS_MSG(E_FAIL, [] { THROW_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__); });
  490. REQUIRE_LOG(E_FAIL, [] { REQUIRE(fTrue == LOG_HR_IF(E_FAIL, fTrue)); });
  491. REQUIRE_LOG_MSG(E_FAIL, [] { REQUIRE(fTrue == LOG_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__)); });
  492. REQUIRE_FAILFAST(E_FAIL, [] { FAIL_FAST_HR_IF(E_FAIL, fTrue); });
  493. REQUIRE_FAILFAST_MSG(E_FAIL, [] { FAIL_FAST_HR_IF_MSG(E_FAIL, fTrue, "msg: %d", __LINE__); });
  494. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF(MDEC(S_OK), MDEC(fFalseRef())); return S_OK; });
  495. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__); return S_OK; });
  496. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_EXPECTED(MDEC(S_OK), MDEC(fFalseRef())); return S_OK; });
  497. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF(MDEC(S_OK), MDEC(fFalseRef()))); });
  498. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  499. REQUIRE_LOG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF(MDEC(S_OK), MDEC(fFalseRef()))); });
  500. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  501. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF(MDEC(S_OK), MDEC(fFalseRef()))); });
  502. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  503. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF(E_FAIL, MDEC(fFalseRef())); return S_OK; });
  504. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__); return S_OK; });
  505. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_EXPECTED(E_FAIL, MDEC(fFalseRef())); return S_OK; });
  506. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF(E_FAIL, MDEC(fFalseRef()))); });
  507. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  508. REQUIRE_LOG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF(E_FAIL, MDEC(fFalseRef()))); });
  509. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  510. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF(E_FAIL, MDEC(fFalseRef()))); });
  511. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  512. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF(MDEC(S_OK), MDEC(fFalseRef())); return S_OK; });
  513. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__); return S_OK; });
  514. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_EXPECTED(MDEC(S_OK), MDEC(fFalseRef())); return S_OK; });
  515. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF(MDEC(S_OK), MDEC(fFalseRef()))); });
  516. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  517. REQUIRE_LOG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF(MDEC(S_OK), MDEC(fFalseRef()))); });
  518. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  519. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF(MDEC(S_OK), MDEC(fFalseRef()))); });
  520. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF_MSG(MDEC(S_OK), MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  521. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF(E_FAIL, MDEC(fFalseRef())); return S_OK; });
  522. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__); return S_OK; });
  523. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_EXPECTED(E_FAIL, MDEC(fFalseRef())); return S_OK; });
  524. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF(E_FAIL, MDEC(fFalseRef()))); });
  525. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(fFalse == THROW_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  526. REQUIRE_LOG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF(E_FAIL, MDEC(fFalseRef()))); });
  527. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(fFalse == LOG_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  528. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF(E_FAIL, MDEC(fFalseRef()))); });
  529. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_HR_IF_MSG(E_FAIL, MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  530. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF_NULL(S_OK, pNull); return S_OK; });
  531. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_NULL_MSG(S_OK, pNull, "msg: %d", __LINE__); return S_OK; });
  532. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_NULL_EXPECTED(S_OK, pNull); return S_OK; });
  533. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR_IF_NULL(S_OK, pNull); });
  534. REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_HR_IF_NULL_MSG(S_OK, pNull, "msg: %d", __LINE__); });
  535. REQUIRE_RETURNS(E_FAIL, [] { RETURN_HR_IF_NULL(E_FAIL, pNull); return S_OK; });
  536. REQUIRE_RETURNS_MSG(E_FAIL, [] { RETURN_HR_IF_NULL_MSG(E_FAIL, pNull, "msg: %d", __LINE__); return S_OK; });
  537. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { RETURN_HR_IF_NULL_EXPECTED(E_FAIL, pNull); return S_OK; });
  538. REQUIRE_THROWS_RESULT(E_FAIL, [] { THROW_HR_IF_NULL(E_FAIL, pNull); });
  539. REQUIRE_THROWS_MSG(E_FAIL, [] { THROW_HR_IF_NULL_MSG(E_FAIL, pNull, "msg: %d", __LINE__); });
  540. REQUIRE_LOG(E_FAIL, [] { REQUIRE(pNull == LOG_HR_IF_NULL(E_FAIL, pNull)); });
  541. REQUIRE_LOG_MSG(E_FAIL, [] { REQUIRE(pNull == LOG_HR_IF_NULL_MSG(E_FAIL, pNull, "msg: %d", __LINE__)); });
  542. REQUIRE_FAILFAST(E_FAIL, [] { FAIL_FAST_HR_IF_NULL(E_FAIL, pNull); });
  543. REQUIRE_FAILFAST_MSG(E_FAIL, [] { FAIL_FAST_HR_IF_NULL_MSG(E_FAIL, pNull, "msg: %d", __LINE__); });
  544. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF_NULL(MDEC(S_OK), MDEC(pValidRef())); return S_OK; });
  545. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_NULL_MSG(MDEC(S_OK), MDEC(pValidRef()), "msg: %d", __LINE__); return S_OK; });
  546. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_NULL_EXPECTED(MDEC(S_OK), MDEC(pValidRef())); return S_OK; });
  547. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(pValid == THROW_HR_IF_NULL(MDEC(S_OK), MDEC(pValidRef()))); });
  548. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(pValid == THROW_HR_IF_NULL_MSG(MDEC(S_OK), MDEC(pValidRef()), "msg: %d", __LINE__)); });
  549. REQUIRE_LOG(S_OK, [] { REQUIRE(pValid == LOG_HR_IF_NULL(MDEC(S_OK), MDEC(pValidRef()))); });
  550. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(pValid == LOG_HR_IF_NULL_MSG(MDEC(S_OK), MDEC(pValidRef()), "msg: %d", __LINE__)); });
  551. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(pValid == FAIL_FAST_HR_IF_NULL(MDEC(S_OK), MDEC(pValidRef()))); });
  552. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(pValid == FAIL_FAST_HR_IF_NULL_MSG(MDEC(S_OK), MDEC(pValidRef()), "msg: %d", __LINE__)); });
  553. REQUIRE_RETURNS(S_OK, [] { RETURN_HR_IF_NULL(E_FAIL, MDEC(pValidRef())); return S_OK; });
  554. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_HR_IF_NULL_MSG(E_FAIL, MDEC(pValidRef()), "msg: %d", __LINE__); return S_OK; });
  555. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_HR_IF_NULL_EXPECTED(E_FAIL, MDEC(pValidRef())); return S_OK; });
  556. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(pValid == THROW_HR_IF_NULL(E_FAIL, MDEC(pValidRef()))); });
  557. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(pValid == THROW_HR_IF_NULL_MSG(E_FAIL, MDEC(pValidRef()), "msg: %d", __LINE__)); });
  558. REQUIRE_LOG(S_OK, [] { REQUIRE(pValid == LOG_HR_IF_NULL(E_FAIL, MDEC(pValidRef()))); });
  559. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(pValid == LOG_HR_IF_NULL_MSG(E_FAIL, MDEC(pValidRef()), "msg: %d", __LINE__)); });
  560. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(pValid == FAIL_FAST_HR_IF_NULL(E_FAIL, MDEC(pValidRef()))); });
  561. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(pValid == FAIL_FAST_HR_IF_NULL_MSG(E_FAIL, MDEC(pValidRef()), "msg: %d", __LINE__)); });
  562. REQUIRE_FAILFAST_UNSPECIFIED([] { ::SetLastError(0); FAIL_FAST_LAST_ERROR_IF(fTrue); });
  563. REQUIRE_FAILFAST_UNSPECIFIED([] { ::SetLastError(0); FAIL_FAST_LAST_ERROR_IF_MSG(fTrue, "msg: %d", __LINE__); });
  564. REQUIRE_RETURNS(E_AD, [] { SetAD(); RETURN_LAST_ERROR_IF(fTrue); return S_OK; });
  565. REQUIRE_RETURNS_MSG(E_AD, [] { SetAD(); RETURN_LAST_ERROR_IF_MSG(fTrue, "msg: %d", __LINE__); return S_OK; });
  566. REQUIRE_RETURNS_EXPECTED(E_AD, [] { SetAD(); RETURN_LAST_ERROR_IF_EXPECTED(fTrue); return S_OK; });
  567. REQUIRE_THROWS_RESULT(E_AD, [] { SetAD(); THROW_LAST_ERROR_IF(fTrue); });
  568. REQUIRE_THROWS_MSG(E_AD, [] { SetAD(); THROW_LAST_ERROR_IF_MSG(fTrue, "msg: %d", __LINE__); });
  569. REQUIRE_LOG(E_AD, [] { SetAD(); REQUIRE(fTrue == LOG_LAST_ERROR_IF(fTrue)); });
  570. REQUIRE_LOG_MSG(E_AD, [] { SetAD(); REQUIRE(fTrue == LOG_LAST_ERROR_IF_MSG(fTrue, "msg: %d", __LINE__)); });
  571. REQUIRE_FAILFAST(E_AD, [] { SetAD(); FAIL_FAST_LAST_ERROR_IF(fTrue); });
  572. REQUIRE_FAILFAST_MSG(E_AD, [] { SetAD(); FAIL_FAST_LAST_ERROR_IF_MSG(fTrue, "msg: %d", __LINE__); });
  573. REQUIRE_RETURNS(S_OK, [] { RETURN_LAST_ERROR_IF(MDEC(fFalseRef())); return S_OK; });
  574. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_LAST_ERROR_IF_MSG(MDEC(fFalseRef()), "msg: %d", __LINE__); return S_OK; });
  575. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_LAST_ERROR_IF_EXPECTED(MDEC(fFalseRef())); return S_OK; });
  576. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(fFalse == THROW_LAST_ERROR_IF(MDEC(fFalseRef()))); });
  577. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(fFalse == THROW_LAST_ERROR_IF_MSG(MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  578. REQUIRE_LOG(S_OK, [] { REQUIRE(fFalse == LOG_LAST_ERROR_IF(MDEC(fFalseRef()))); });
  579. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(fFalse == LOG_LAST_ERROR_IF_MSG(MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  580. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_LAST_ERROR_IF(MDEC(fFalseRef()))); });
  581. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_LAST_ERROR_IF_MSG(MDEC(fFalseRef()), "msg: %d", __LINE__)); });
  582. REQUIRE_FAILFAST_UNSPECIFIED([] { ::SetLastError(0); FAIL_FAST_LAST_ERROR_IF_NULL(pNull); });
  583. REQUIRE_FAILFAST_UNSPECIFIED([] { ::SetLastError(0); FAIL_FAST_LAST_ERROR_IF_NULL_MSG(pNull, "msg: %d", __LINE__); });
  584. REQUIRE_RETURNS(E_AD, [] { SetAD(); RETURN_LAST_ERROR_IF_NULL(pNull); return S_OK; });
  585. REQUIRE_RETURNS_MSG(E_AD, [] { SetAD(); RETURN_LAST_ERROR_IF_NULL_MSG(pNull, "msg: %d", __LINE__); return S_OK; });
  586. REQUIRE_RETURNS_EXPECTED(E_AD, [] { SetAD(); RETURN_LAST_ERROR_IF_NULL_EXPECTED(pNull); return S_OK; });
  587. REQUIRE_THROWS_RESULT(E_AD, [] { SetAD(); THROW_LAST_ERROR_IF_NULL(pNull); });
  588. REQUIRE_THROWS_MSG(E_AD, [] { SetAD(); THROW_LAST_ERROR_IF_NULL_MSG(pNull, "msg: %d", __LINE__); });
  589. REQUIRE_LOG(E_AD, [] { SetAD(); REQUIRE(pNull == LOG_LAST_ERROR_IF_NULL(pNull)); });
  590. REQUIRE_LOG_MSG(E_AD, [] { SetAD(); REQUIRE(pNull == LOG_LAST_ERROR_IF_NULL_MSG(pNull, "msg: %d", __LINE__)); });
  591. REQUIRE_FAILFAST(E_AD, [] { SetAD(); FAIL_FAST_LAST_ERROR_IF_NULL(pNull); });
  592. REQUIRE_FAILFAST_MSG(E_AD, [] { SetAD(); FAIL_FAST_LAST_ERROR_IF_NULL_MSG(pNull, "msg: %d", __LINE__); });
  593. REQUIRE_RETURNS(S_OK, [] { RETURN_LAST_ERROR_IF_NULL(MDEC(pValidRef())); return S_OK; });
  594. REQUIRE_RETURNS_MSG(S_OK, [] { RETURN_LAST_ERROR_IF_NULL_MSG(MDEC(pValidRef()), "msg: %d", __LINE__); return S_OK; });
  595. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_LAST_ERROR_IF_NULL_EXPECTED(MDEC(pValidRef())); return S_OK; });
  596. REQUIRE_THROWS_RESULT(S_OK, [] { REQUIRE(pNull != THROW_LAST_ERROR_IF_NULL(MDEC(pValidRef()))); });
  597. REQUIRE_THROWS_MSG(S_OK, [] { REQUIRE(pNull != THROW_LAST_ERROR_IF_NULL_MSG(MDEC(pValidRef()), "msg: %d", __LINE__)); });
  598. REQUIRE_LOG(S_OK, [] { REQUIRE(pNull != LOG_LAST_ERROR_IF_NULL(MDEC(pValidRef()))); });
  599. REQUIRE_LOG_MSG(S_OK, [] { REQUIRE(pNull != LOG_LAST_ERROR_IF_NULL_MSG(MDEC(pValidRef()), "msg: %d", __LINE__)); });
  600. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(pNull != FAIL_FAST_LAST_ERROR_IF_NULL(MDEC(pValidRef()))); });
  601. REQUIRE_FAILFAST_MSG(S_OK, [] { REQUIRE(pNull != FAIL_FAST_LAST_ERROR_IF_NULL_MSG(MDEC(pValidRef()), "msg: %d", __LINE__)); });
  602. REQUIRE_LOG(S_OK, [] { REQUIRE(true == SUCCEEDED_LOG(MDEC(S_OK))); });
  603. REQUIRE_LOG(E_FAIL, [] { REQUIRE(false == SUCCEEDED_LOG(E_FAIL)); });
  604. REQUIRE_LOG(S_OK, [] { REQUIRE(false == FAILED_LOG(MDEC(S_OK))); });
  605. REQUIRE_LOG(E_FAIL, [] { REQUIRE(true == FAILED_LOG(E_FAIL)); });
  606. REQUIRE_LOG(ERROR_SUCCESS, [] { REQUIRE(true == SUCCEEDED_WIN32_LOG(MDEC(ERROR_SUCCESS))); });
  607. REQUIRE_LOG(HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), [] { REQUIRE(false == SUCCEEDED_WIN32_LOG(ERROR_ACCESS_DENIED)); });
  608. REQUIRE_LOG(ERROR_SUCCESS, [] { REQUIRE(false == FAILED_WIN32_LOG(MDEC(ERROR_SUCCESS))); });
  609. REQUIRE_LOG(HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), [] { REQUIRE(true == FAILED_WIN32_LOG(ERROR_ACCESS_DENIED)); });
  610. REQUIRE_LOG(ntOK, [] { REQUIRE(true == SUCCEEDED_NTSTATUS_LOG(MDEC(ntOK))); });
  611. REQUIRE_LOG(wil::details::NtStatusToHr(ntFAIL), [] { REQUIRE(false == SUCCEEDED_NTSTATUS_LOG(ntFAIL)); });
  612. REQUIRE_LOG(ntOK, [] { REQUIRE(false == FAILED_NTSTATUS_LOG(MDEC(ntOK))); });
  613. REQUIRE_LOG(wil::details::NtStatusToHr(ntFAIL), [] { REQUIRE(true == FAILED_NTSTATUS_LOG(ntFAIL)); });
  614. // FAIL_FAST_IMMEDIATE* directly invokes __fastfail, which we can't catch, so disabled for now
  615. // REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_IMMEDIATE(); });
  616. // REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_IMMEDIATE_IF_FAILED(E_FAIL); });
  617. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(S_OK == FAIL_FAST_IMMEDIATE_IF_FAILED(MDEC(S_OK))); });
  618. // REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_IMMEDIATE_IF(fTrue); });
  619. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(fFalse == FAIL_FAST_IMMEDIATE_IF(MDEC(fFalseRef()))); });
  620. // REQUIRE_FAILFAST_UNSPECIFIED([] { FAIL_FAST_IMMEDIATE_IF_NULL(pNull); });
  621. REQUIRE_FAILFAST(S_OK, [] { REQUIRE(pValid == FAIL_FAST_IMMEDIATE_IF_NULL(MDEC(pValidRef()))); });
  622. #ifdef WIL_ENABLE_EXCEPTIONS
  623. REQUIRE_RETURNS(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_RETURN(); return S_OK; });
  624. REQUIRE_RETURNS_MSG(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_RETURN_MSG("msg: %d", __LINE__); return S_OK; });
  625. REQUIRE_RETURNS_EXPECTED(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_RETURN_EXPECTED(); return S_OK; });
  626. REQUIRE_LOG(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_LOG(); });
  627. REQUIRE_LOG_MSG(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_LOG_MSG("msg: %d", __LINE__); });
  628. REQUIRE_FAILFAST(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_FAIL_FAST(); });
  629. REQUIRE_FAILFAST_MSG(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_FAIL_FAST_MSG("msg: %d", __LINE__); });
  630. REQUIRE_THROWS_RESULT(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_THROW_NORMALIZED(); });
  631. REQUIRE_THROWS_MSG(S_OK, [] { try { THROW_IF_FAILED(hrOK); } CATCH_THROW_NORMALIZED_MSG("msg: %d", __LINE__); });
  632. REQUIRE_RETURNS(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_RETURN(); return S_OK; });
  633. REQUIRE_RETURNS_MSG(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_RETURN_MSG("msg: %d", __LINE__); return S_OK; });
  634. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_RETURN_EXPECTED(); return S_OK; });
  635. REQUIRE_LOG(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_LOG(); });
  636. REQUIRE_LOG_MSG(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_LOG_MSG("msg: %d", __LINE__); });
  637. REQUIRE_FAILFAST(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_FAIL_FAST(); });
  638. REQUIRE_FAILFAST_MSG(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_FAIL_FAST_MSG("msg: %d", __LINE__); });
  639. REQUIRE_THROWS_RESULT(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_THROW_NORMALIZED(); });
  640. REQUIRE_THROWS_MSG(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_THROW_NORMALIZED_MSG("msg: %d", __LINE__); });
  641. REQUIRE_FAILFAST_UNSPECIFIED([] { try { if (FAILED(hrFAIL)) { throw E_FAIL; } } CATCH_FAIL_FAST(); });
  642. REQUIRE_FAILFAST_UNSPECIFIED([] { try { if (FAILED(hrFAIL)) { throw E_FAIL; } } CATCH_FAIL_FAST_MSG("msg: %d", __LINE__); });
  643. REQUIRE_THROWS_RESULT(E_AD, [] { THROW_EXCEPTION(MDEC(DerivedAccessDeniedException())); });
  644. REQUIRE_THROWS_MSG(E_AD, [] { THROW_EXCEPTION_MSG(MDEC(DerivedAccessDeniedException()), "msg: %d", __LINE__); });
  645. REQUIRE_LOG(E_AD, [] { try { throw AlternateAccessDeniedException(); } CATCH_LOG(); });
  646. REQUIRE_THROWS_RESULT(E_AD, [] { try { throw AlternateAccessDeniedException(); } CATCH_THROW_NORMALIZED(); });
  647. REQUIRE_RETURNS(S_OK, [] { return wil::ResultFromException([] { THROW_IF_FAILED(hrOK); }); });
  648. REQUIRE_RETURNS(E_FAIL, [] { return wil::ResultFromException([] { THROW_IF_FAILED(hrFAIL); }); });
  649. REQUIRE(E_AD == wil::ResultFromException([] { throw AlternateAccessDeniedException(); }));
  650. try { THROW_HR(E_FAIL); }
  651. catch (...) { REQUIRE(E_FAIL == wil::ResultFromCaughtException()); };
  652. #endif
  653. #ifdef WIL_ENABLE_EXCEPTIONS
  654. REQUIRE_LOG(E_FAIL, [] { try { THROW_IF_FAILED(hrFAIL); } CATCH_LOG(); });
  655. #endif
  656. REQUIRE_RETURNS(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; RETURN_IF_NULL_ALLOC(MDEC(pInt)); return S_OK; });
  657. REQUIRE_RETURNS_MSG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; RETURN_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); return S_OK; });
  658. REQUIRE_RETURNS_EXPECTED(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; RETURN_IF_NULL_ALLOC_EXPECTED(MDEC(pInt)); return S_OK; });
  659. REQUIRE_RETURNS(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); RETURN_IF_NULL_ALLOC(MDEC(pInt)); return S_OK; });
  660. REQUIRE_RETURNS_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); RETURN_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); return S_OK; });
  661. REQUIRE_RETURNS_EXPECTED(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); RETURN_IF_NULL_ALLOC_EXPECTED(MDEC(pInt)); return S_OK; });
  662. REQUIRE_RETURNS(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; RETURN_HR_IF_NULL(E_OUTOFMEMORY, MDEC(pInt)); return S_OK; });
  663. REQUIRE_RETURNS_MSG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; RETURN_HR_IF_NULL_MSG(E_OUTOFMEMORY, pInt, "msg: %d", __LINE__); return S_OK; });
  664. REQUIRE_RETURNS_EXPECTED(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; RETURN_HR_IF_NULL_EXPECTED(E_OUTOFMEMORY, MDEC(pInt)); return S_OK; });
  665. REQUIRE_RETURNS(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); RETURN_HR_IF_NULL(E_OUTOFMEMORY, MDEC(pInt)); return S_OK; });
  666. REQUIRE_RETURNS_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); RETURN_HR_IF_NULL_MSG(E_OUTOFMEMORY, MDEC(pInt), "msg: %d", __LINE__); return S_OK; });
  667. REQUIRE_RETURNS_EXPECTED(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); RETURN_HR_IF_NULL_EXPECTED(E_OUTOFMEMORY, MDEC(pInt)); return S_OK; });
  668. REQUIRE_RETURNS(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); RETURN_LAST_ERROR_IF_NULL(MDEC(pInt)); return S_OK; });
  669. REQUIRE_RETURNS_MSG(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); RETURN_LAST_ERROR_IF_NULL_MSG(MDEC(pInt), "msg: %d", __LINE__); return S_OK; });
  670. REQUIRE_RETURNS_EXPECTED(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); RETURN_LAST_ERROR_IF_NULL_EXPECTED(MDEC(pInt)); return S_OK; });
  671. REQUIRE_RETURNS(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); SetAD(); RETURN_LAST_ERROR_IF_NULL(MDEC(pInt)); return S_OK; });
  672. REQUIRE_RETURNS_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); SetAD(); RETURN_LAST_ERROR_IF_NULL_MSG(MDEC(pInt), "msg: %d", __LINE__); return S_OK; });
  673. REQUIRE_RETURNS_EXPECTED(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); SetAD(); RETURN_LAST_ERROR_IF_NULL_EXPECTED(MDEC(pInt)); return S_OK; });
  674. REQUIRE_THROWS_RESULT(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; THROW_IF_NULL_ALLOC(MDEC(pInt)); });
  675. REQUIRE_THROWS_MSG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; THROW_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  676. REQUIRE_LOG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; LOG_IF_NULL_ALLOC(MDEC(pInt)); });
  677. REQUIRE_LOG_MSG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; LOG_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  678. REQUIRE_FAILFAST(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; FAIL_FAST_IF_NULL_ALLOC(MDEC(pInt)); });
  679. REQUIRE_FAILFAST_MSG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; FAIL_FAST_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  680. REQUIRE_THROWS_RESULT(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); THROW_IF_NULL_ALLOC(MDEC(pInt)); });
  681. REQUIRE_THROWS_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); THROW_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  682. REQUIRE_LOG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); LOG_IF_NULL_ALLOC(MDEC(pInt)); });
  683. REQUIRE_LOG_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); LOG_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  684. REQUIRE_FAILFAST(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_IF_NULL_ALLOC(MDEC(pInt)); });
  685. REQUIRE_FAILFAST_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_IF_NULL_ALLOC_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  686. REQUIRE_LOG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; LOG_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(pInt)); });
  687. REQUIRE_LOG_MSG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; LOG_HR_IF_NULL_MSG(MDEC(E_OUTOFMEMORY), MDEC(pInt), "msg: %d", __LINE__); });
  688. REQUIRE_FAILFAST(E_FAIL, [] { std::unique_ptr<int> pInt; FAIL_FAST_HR_IF_NULL(MDEC(E_FAIL), MDEC(pInt)); });
  689. REQUIRE_FAILFAST_MSG(E_FAIL, [] { std::unique_ptr<int> pInt; FAIL_FAST_HR_IF_NULL_MSG(MDEC(E_FAIL), MDEC(pInt), "msg: %d", __LINE__); });
  690. REQUIRE_THROWS_RESULT(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; THROW_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(pInt)); });
  691. REQUIRE_THROWS_MSG(E_OUTOFMEMORY, [] { std::unique_ptr<int> pInt; THROW_HR_IF_NULL_MSG(MDEC(E_OUTOFMEMORY), MDEC(pInt), "msg: %d", __LINE__); });
  692. REQUIRE_LOG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); LOG_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(pInt)); });
  693. REQUIRE_LOG_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); LOG_HR_IF_NULL_MSG(MDEC(E_OUTOFMEMORY), MDEC(pInt), "msg: %d", __LINE__); });
  694. REQUIRE_FAILFAST(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_HR_IF_NULL(MDEC(E_FAIL), MDEC(pInt)); });
  695. REQUIRE_FAILFAST_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_HR_IF_NULL_MSG(MDEC(E_FAIL), MDEC(pInt), "msg: %d", __LINE__); });
  696. REQUIRE_THROWS_RESULT(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); THROW_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(pInt)); });
  697. REQUIRE_THROWS_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); THROW_HR_IF_NULL_MSG(MDEC(E_OUTOFMEMORY), MDEC(pInt), "msg: %d", __LINE__); });
  698. REQUIRE_LOG(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); LOG_LAST_ERROR_IF_NULL(MDEC(pInt)); });
  699. REQUIRE_LOG_MSG(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); LOG_LAST_ERROR_IF_NULL_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  700. REQUIRE_FAILFAST(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); FAIL_FAST_LAST_ERROR_IF_NULL(pInt); });
  701. REQUIRE_FAILFAST_MSG(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); FAIL_FAST_LAST_ERROR_IF_NULL_MSG(pInt, "msg: %d", __LINE__); });
  702. REQUIRE_THROWS_RESULT(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); THROW_LAST_ERROR_IF_NULL(MDEC(pInt)); });
  703. REQUIRE_THROWS_MSG(E_AD, [] { std::unique_ptr<int> pInt; SetAD(); THROW_LAST_ERROR_IF_NULL_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  704. REQUIRE_LOG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); LOG_LAST_ERROR_IF_NULL(MDEC(pInt)); });
  705. REQUIRE_LOG_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); LOG_LAST_ERROR_IF_NULL_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  706. REQUIRE_FAILFAST(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_LAST_ERROR_IF_NULL(pInt); });
  707. REQUIRE_FAILFAST_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_LAST_ERROR_IF_NULL_MSG(pInt, "msg: %d", __LINE__); });
  708. REQUIRE_THROWS_RESULT(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); THROW_LAST_ERROR_IF_NULL(MDEC(pInt)); });
  709. REQUIRE_THROWS_MSG(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); THROW_LAST_ERROR_IF_NULL_MSG(MDEC(pInt), "msg: %d", __LINE__); });
  710. // REQUIRE_FAILFAST_UNSPECIFIED([] { std::unique_ptr<int> pInt; FAIL_FAST_IMMEDIATE_IF_NULL(pNull); });
  711. REQUIRE_FAILFAST(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_IMMEDIATE_IF_NULL(MDEC(pValidRef())); });
  712. REQUIRE_FAILFAST_UNSPECIFIED([] { std::unique_ptr<int> pInt; FAIL_FAST_IF_NULL(pNull); });
  713. REQUIRE_FAILFAST(S_OK, [] { std::unique_ptr<int> pInt(new int(5)); FAIL_FAST_IF_NULL(MDEC(pInt)); });
  714. REQUIRE_RETURNS(E_OUTOFMEMORY, [] { Microsoft::WRL::ComPtr<IUnknown> ptr; RETURN_IF_NULL_ALLOC(MDEC(ptr)); return S_OK; });
  715. REQUIRE_LOG(E_OUTOFMEMORY, [] { Microsoft::WRL::ComPtr<IUnknown> ptr; LOG_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(ptr)); });
  716. REQUIRE_RETURNS(E_OUTOFMEMORY, [] { std::shared_ptr<int> ptr; RETURN_IF_NULL_ALLOC(MDEC(ptr)); return S_OK; });
  717. REQUIRE_LOG(E_OUTOFMEMORY, [] { std::shared_ptr<int> ptr; LOG_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(ptr)); });
  718. REQUIRE_RETURNS(S_OK, [] { std::shared_ptr<int> ptr(new int(5)); RETURN_IF_NULL_ALLOC(MDEC(ptr)); return S_OK; });
  719. REQUIRE_LOG(S_OK, [] { std::shared_ptr<int> ptr(new int(5)); LOG_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(ptr)); });
  720. #ifdef __cplusplus_winrt
  721. REQUIRE_RETURNS(E_OUTOFMEMORY, [] { Platform::String^ str(nullptr); RETURN_IF_NULL_ALLOC(MDEC(str)); return S_OK; });
  722. REQUIRE_LOG(E_OUTOFMEMORY, [] { Platform::String^ str(nullptr); LOG_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(str)); });
  723. REQUIRE_RETURNS(S_OK, [] { Platform::String^ str(L"a"); RETURN_IF_NULL_ALLOC(MDEC(str)); return S_OK; });
  724. REQUIRE_LOG(S_OK, [] { Platform::String^ str(L"a"); LOG_HR_IF_NULL(MDEC(E_OUTOFMEMORY), MDEC(str)); });
  725. #endif
  726. }
  727. #define WRAP_LAMBDA(code) [&] {code;};
  728. //these macros should all have compile errors due to use of an invalid type
  729. void InvalidTypeChecks()
  730. {
  731. std::unique_ptr<int> boolCastClass;
  732. std::vector<int> noBoolCastClass;
  733. //WRAP_LAMBDA(RETURN_IF_FAILED(fTrue));
  734. //WRAP_LAMBDA(RETURN_IF_FAILED(fTRUE));
  735. //WRAP_LAMBDA(RETURN_IF_FAILED(boolCastClass));
  736. //WRAP_LAMBDA(RETURN_IF_FAILED(noBoolCastClass));
  737. //WRAP_LAMBDA(RETURN_IF_FAILED(errSuccess));
  738. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE(fTrue));
  739. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE(noBoolCastClass));
  740. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE(hrOK));
  741. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE(errSuccess));
  742. //WRAP_LAMBDA(RETURN_HR_IF(errSuccess, false));
  743. //WRAP_LAMBDA(RETURN_HR_IF(errSuccess, true));
  744. //WRAP_LAMBDA(RETURN_HR_IF(hrOK, noBoolCastClass));
  745. //WRAP_LAMBDA(RETURN_HR_IF(hrOK, hrOK));
  746. //WRAP_LAMBDA(RETURN_HR_IF(hrOK, errSuccess));
  747. //WRAP_LAMBDA(RETURN_HR_IF_NULL(errSuccess, nullptr));
  748. //WRAP_LAMBDA(RETURN_HR_IF_NULL(errSuccess, pValid));
  749. //WRAP_LAMBDA(RETURN_LAST_ERROR_IF(noBoolCastClass));
  750. //WRAP_LAMBDA(RETURN_LAST_ERROR_IF(errSuccess));
  751. //WRAP_LAMBDA(RETURN_LAST_ERROR_IF(hrOK));
  752. //WRAP_LAMBDA(RETURN_IF_FAILED_EXPECTED(fTrue));
  753. //WRAP_LAMBDA(RETURN_IF_FAILED_EXPECTED(fTRUE));
  754. //WRAP_LAMBDA(RETURN_IF_FAILED_EXPECTED(boolCastClass));
  755. //WRAP_LAMBDA(RETURN_IF_FAILED_EXPECTED(noBoolCastClass));
  756. //WRAP_LAMBDA(RETURN_IF_FAILED_EXPECTED(errSuccess));
  757. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(fTrue));
  758. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(noBoolCastClass));
  759. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(hrOK));
  760. //WRAP_LAMBDA(RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(errSuccess));
  761. //LOG_IF_FAILED(fTrue);
  762. //LOG_IF_FAILED(fTRUE);
  763. //LOG_IF_FAILED(boolCastClass);
  764. //LOG_IF_FAILED(noBoolCastClass);
  765. //LOG_IF_FAILED(errSuccess);
  766. //LOG_IF_WIN32_BOOL_FALSE(fTrue);
  767. //LOG_IF_WIN32_BOOL_FALSE(noBoolCastClass);
  768. //LOG_IF_WIN32_BOOL_FALSE(hrOK);
  769. //LOG_IF_WIN32_BOOL_FALSE(errSuccess);
  770. //LOG_HR_IF(errSuccess, false);
  771. //LOG_HR_IF(errSuccess, true);
  772. //LOG_HR_IF(hrOK, noBoolCastClass);
  773. //LOG_HR_IF(hrOK, hrOK);
  774. //LOG_HR_IF(hrOK, errSuccess);
  775. //FAIL_FAST_IF_FAILED(fTrue);
  776. //FAIL_FAST_IF_FAILED(fTRUE);
  777. //FAIL_FAST_IF_FAILED(boolCastClass);
  778. //FAIL_FAST_IF_FAILED(noBoolCastClass);
  779. //FAIL_FAST_IF_FAILED(errSuccess);
  780. //FAIL_FAST_IF_WIN32_BOOL_FALSE(fTrue);
  781. //FAIL_FAST_IF_WIN32_BOOL_FALSE(noBoolCastClass);
  782. //FAIL_FAST_IF_WIN32_BOOL_FALSE(hrOK);
  783. //FAIL_FAST_IF_WIN32_BOOL_FALSE(errSuccess);
  784. //FAIL_FAST_HR_IF(errSuccess, false);
  785. //FAIL_FAST_HR_IF(errSuccess, true);
  786. //FAIL_FAST_HR_IF(hrOK, noBoolCastClass);
  787. //FAIL_FAST_HR_IF(hrOK, hrOK);
  788. //FAIL_FAST_HR_IF(hrOK, errSuccess);
  789. //THROW_IF_FAILED(fTrue);
  790. //THROW_IF_FAILED(fTRUE);
  791. //THROW_IF_FAILED(boolCastClass);
  792. //THROW_IF_FAILED(noBoolCastClass);
  793. //THROW_IF_FAILED(errSuccess);
  794. //THROW_IF_WIN32_BOOL_FALSE(fTrue);
  795. //THROW_IF_WIN32_BOOL_FALSE(noBoolCastClass);
  796. //THROW_IF_WIN32_BOOL_FALSE(hrOK);
  797. //THROW_IF_WIN32_BOOL_FALSE(errSuccess);
  798. //THROW_HR_IF(errSuccess, false);
  799. //THROW_HR_IF(errSuccess, true);
  800. //THROW_HR_IF(hrOK, noBoolCastClass);
  801. //THROW_HR_IF(hrOK, hrOK);
  802. //THROW_HR_IF(hrOK, errSuccess);
  803. //FAIL_FAST_IF(noBoolCastClass);
  804. //FAIL_FAST_IF(hrOK);
  805. //FAIL_FAST_IF(errSuccess);
  806. //FAIL_FAST_IMMEDIATE_IF_FAILED(fTrue);
  807. //FAIL_FAST_IMMEDIATE_IF_FAILED(fTRUE);
  808. //FAIL_FAST_IMMEDIATE_IF_FAILED(boolCastClass);
  809. //FAIL_FAST_IMMEDIATE_IF_FAILED(noBoolCastClass);
  810. //FAIL_FAST_IMMEDIATE_IF_FAILED(errSuccess);
  811. //FAIL_FAST_IMMEDIATE_IF(noBoolCastClass);
  812. //FAIL_FAST_IMMEDIATE_IF(hrOK);
  813. //FAIL_FAST_IMMEDIATE_IF(errSuccess);
  814. }
  815. TEST_CASE("WindowsInternalTests::UniqueHandle", "[resource][unique_any]")
  816. {
  817. {
  818. // default construction test
  819. wil::unique_handle spHandle;
  820. REQUIRE(spHandle.get() == nullptr);
  821. // null ptr assignment creation
  822. wil::unique_handle spNullHandle = nullptr;
  823. REQUIRE(spNullHandle.get() == nullptr);
  824. // explicit construction from the invalid value
  825. wil::unique_handle spInvalidHandle(nullptr);
  826. REQUIRE(spInvalidHandle.get() == nullptr);
  827. // valid handle creation
  828. wil::unique_handle spValidHandle(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  829. REQUIRE(spValidHandle.get() != nullptr);
  830. auto const handleValue = spValidHandle.get();
  831. // r-value construction
  832. wil::unique_handle spMoveHandle = wistd::move(spValidHandle);
  833. REQUIRE(spValidHandle.get() == nullptr);
  834. REQUIRE(spMoveHandle.get() == handleValue);
  835. // nullptr-assignment
  836. spNullHandle = nullptr;
  837. REQUIRE(spNullHandle.get() == nullptr);
  838. // r-value assignment
  839. spValidHandle = wistd::move(spMoveHandle);
  840. REQUIRE(spValidHandle.get() == handleValue);
  841. REQUIRE(spMoveHandle.get() == nullptr);
  842. // swap
  843. spValidHandle.swap(spMoveHandle);
  844. REQUIRE(spValidHandle.get() == nullptr);
  845. REQUIRE(spMoveHandle.get() == handleValue);
  846. // operator bool
  847. REQUIRE_FALSE(spValidHandle);
  848. REQUIRE(spMoveHandle);
  849. // release
  850. auto ptrValidHandle = spValidHandle.release();
  851. auto ptrMoveHandle = spMoveHandle.release();
  852. REQUIRE(ptrValidHandle == nullptr);
  853. REQUIRE(ptrMoveHandle == handleValue);
  854. REQUIRE(spValidHandle.get() == nullptr);
  855. REQUIRE(spMoveHandle.get() == nullptr);
  856. // reset
  857. spValidHandle.reset();
  858. spMoveHandle.reset();
  859. REQUIRE(spValidHandle.get() == nullptr);
  860. REQUIRE(spMoveHandle.get() == nullptr);
  861. spValidHandle.reset(ptrValidHandle);
  862. spMoveHandle.reset(ptrMoveHandle);
  863. REQUIRE(spValidHandle.get() == nullptr);
  864. REQUIRE(spMoveHandle.get() == handleValue);
  865. spNullHandle.reset(nullptr);
  866. REQUIRE(spNullHandle.get() == nullptr);
  867. // address
  868. REQUIRE(*spMoveHandle.addressof() == handleValue);
  869. REQUIRE(*spMoveHandle.put() == nullptr);
  870. *spMoveHandle.put() = ::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0);
  871. REQUIRE(spMoveHandle);
  872. REQUIRE(*(&spMoveHandle) == nullptr);
  873. *(&spMoveHandle) = ::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0);
  874. REQUIRE(spMoveHandle);
  875. }
  876. {
  877. // default construction test
  878. wil::unique_hfile spHandle;
  879. REQUIRE(spHandle.get() == INVALID_HANDLE_VALUE);
  880. // implicit construction from the invalid value
  881. wil::unique_hfile spNullHandle; // = nullptr; // method explicitly disabled as nullptr isn't the invalid value
  882. REQUIRE(spNullHandle.get() == INVALID_HANDLE_VALUE);
  883. // assignment from the invalid value
  884. // spNullHandle = nullptr; // method explicitly disabled as nullptr isn't the invalid value
  885. REQUIRE(spNullHandle.get() == INVALID_HANDLE_VALUE);
  886. // explicit construction from the invalid value
  887. wil::unique_hfile spInvalidHandle(INVALID_HANDLE_VALUE);
  888. REQUIRE(spInvalidHandle.get() == INVALID_HANDLE_VALUE);
  889. // valid handle creation
  890. wchar_t tempFileName[MAX_PATH];
  891. REQUIRE_SUCCEEDED(witest::GetTempFileName(tempFileName));
  892. #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
  893. CREATEFILE2_EXTENDED_PARAMETERS params = { sizeof(params) };
  894. params.dwFileAttributes = FILE_ATTRIBUTE_TEMPORARY;
  895. wil::unique_hfile spValidHandle(::CreateFile2(tempFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE, CREATE_ALWAYS, &params));
  896. #else
  897. wil::unique_hfile spValidHandle(::CreateFileW(tempFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, nullptr));
  898. #endif
  899. ::DeleteFileW(tempFileName);
  900. REQUIRE(spValidHandle.get() != INVALID_HANDLE_VALUE);
  901. auto const handleValue = spValidHandle.get();
  902. // r-value construction
  903. wil::unique_hfile spMoveHandle = wistd::move(spValidHandle);
  904. REQUIRE(spValidHandle.get() == INVALID_HANDLE_VALUE);
  905. REQUIRE(spMoveHandle.get() == handleValue);
  906. // nullptr-assignment -- uncomment to check intentional compilation error
  907. // spNullHandle = nullptr;
  908. // r-value assignment
  909. spValidHandle = wistd::move(spMoveHandle);
  910. REQUIRE(spValidHandle.get() == handleValue);
  911. REQUIRE(spMoveHandle.get() == INVALID_HANDLE_VALUE);
  912. // swap
  913. spValidHandle.swap(spMoveHandle);
  914. REQUIRE(spValidHandle.get() == INVALID_HANDLE_VALUE);
  915. REQUIRE(spMoveHandle.get() == handleValue);
  916. // operator bool
  917. REQUIRE_FALSE(spValidHandle);
  918. REQUIRE(spMoveHandle);
  919. // release
  920. auto ptrValidHandle = spValidHandle.release();
  921. auto ptrMoveHandle = spMoveHandle.release();
  922. REQUIRE(ptrValidHandle == INVALID_HANDLE_VALUE);
  923. REQUIRE(ptrMoveHandle == handleValue);
  924. REQUIRE(spValidHandle.get() == INVALID_HANDLE_VALUE);
  925. REQUIRE(spMoveHandle.get() == INVALID_HANDLE_VALUE);
  926. // reset
  927. spValidHandle.reset();
  928. spMoveHandle.reset();
  929. REQUIRE(spValidHandle.get() == INVALID_HANDLE_VALUE);
  930. REQUIRE(spMoveHandle.get() == INVALID_HANDLE_VALUE);
  931. spValidHandle.reset(ptrValidHandle);
  932. spMoveHandle.reset(ptrMoveHandle);
  933. REQUIRE(spValidHandle.get() == INVALID_HANDLE_VALUE);
  934. REQUIRE(spMoveHandle.get() == handleValue);
  935. // uncomment to test intentional compilation error due to conflict with INVALID_HANDLE_VALUE
  936. // spNullHandle.reset(nullptr);
  937. // address
  938. REQUIRE(*spMoveHandle.addressof() == handleValue);
  939. REQUIRE(*(&spMoveHandle) == INVALID_HANDLE_VALUE);
  940. wchar_t tempFileName2[MAX_PATH];
  941. REQUIRE_SUCCEEDED(witest::GetTempFileName(tempFileName2));
  942. #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
  943. CREATEFILE2_EXTENDED_PARAMETERS params2 = { sizeof(params2) };
  944. params2.dwFileAttributes = FILE_ATTRIBUTE_TEMPORARY;
  945. *(&spMoveHandle) = ::CreateFile2(tempFileName2, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE, CREATE_ALWAYS, &params2);
  946. #else
  947. *(&spMoveHandle) = ::CreateFileW(tempFileName2, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, nullptr);
  948. #endif
  949. ::DeleteFileW(tempFileName2);
  950. REQUIRE(spMoveHandle);
  951. // ensure that mistaken nullptr usage is not valid...
  952. spMoveHandle.reset();
  953. *(&spMoveHandle) = nullptr;
  954. REQUIRE_FALSE(spMoveHandle);
  955. }
  956. auto hFirst = ::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0);
  957. auto hSecond= ::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0);
  958. wil::unique_handle spLeft(hFirst);
  959. wil::unique_handle spRight(hSecond);
  960. REQUIRE(spRight.get() == hSecond);
  961. REQUIRE(spLeft.get() == hFirst);
  962. swap(spLeft, spRight);
  963. REQUIRE(spLeft.get() == hSecond);
  964. REQUIRE(spRight.get() == hFirst);
  965. swap(spLeft, spRight);
  966. REQUIRE((spLeft.get() == spRight.get()) == (spLeft == spRight));
  967. REQUIRE((spLeft.get() != spRight.get()) == (spLeft != spRight));
  968. REQUIRE((spLeft.get() < spRight.get()) == (spLeft < spRight));
  969. REQUIRE((spLeft.get() <= spRight.get()) == (spLeft <= spRight));
  970. REQUIRE((spLeft.get() >= spRight.get()) == (spLeft >= spRight));
  971. REQUIRE((spLeft.get() > spRight.get()) == (spLeft > spRight));
  972. // test stl container use (hash & std::less)
  973. #ifdef WIL_ENABLE_EXCEPTIONS
  974. std::unordered_set<wil::unique_handle> hashSet;
  975. hashSet.insert(std::move(spLeft));
  976. hashSet.insert(std::move(spRight));
  977. std::multiset<wil::unique_handle> set;
  978. set.insert(std::move(spLeft));
  979. set.insert(std::move(spRight));
  980. #endif
  981. }
  982. #ifdef WIL_ENABLE_EXCEPTIONS
  983. TEST_CASE("WindowsInternalTests::SharedHandle", "[resource][shared_any]")
  984. {
  985. // default construction
  986. wil::shared_handle spHandle;
  987. REQUIRE(spHandle.get() == nullptr);
  988. // pointer construction
  989. wil::shared_handle spValid(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  990. auto ptr = spValid.get();
  991. REQUIRE(spValid.get() != nullptr);
  992. // null construction
  993. wil::shared_handle spNull = nullptr;
  994. REQUIRE(spNull.get() == nullptr);
  995. // Present to verify that it doesn't compile (disabled)
  996. // wil::shared_hfile spFile = nullptr;
  997. // copy construction
  998. wil::shared_handle spCopy = spValid;
  999. REQUIRE(spCopy.get() == ptr);
  1000. // r-value construction
  1001. wil::shared_handle spMove = wistd::move(spCopy);
  1002. REQUIRE(spMove.get() == ptr);
  1003. REQUIRE(spCopy.get() == nullptr);
  1004. // unique handle construction
  1005. wil::shared_handle spFromUnique = wil::unique_handle(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  1006. REQUIRE(spFromUnique.get() != nullptr);
  1007. // direct assignment
  1008. wil::shared_handle spAssign;
  1009. spAssign = spValid;
  1010. REQUIRE(spAssign.get() == ptr);
  1011. // empty reset
  1012. spFromUnique.reset();
  1013. REQUIRE(spFromUnique.get() == nullptr);
  1014. // reset against unique ptr
  1015. spFromUnique.reset(wil::unique_handle(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0)));
  1016. REQUIRE(spFromUnique.get() != nullptr);
  1017. // reset against raw pointer
  1018. spAssign.reset(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  1019. REQUIRE(spAssign.get() != nullptr);
  1020. REQUIRE(spAssign.get() != ptr);
  1021. // ref-count checks
  1022. REQUIRE(spAssign.use_count() == 1);
  1023. // bool operator
  1024. REQUIRE(spAssign);
  1025. spAssign.reset();
  1026. REQUIRE_FALSE(spAssign);
  1027. // swap and compare
  1028. wil::shared_handle sp1(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  1029. wil::shared_handle sp2(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  1030. auto ptr1 = sp1.get();
  1031. auto ptr2 = sp2.get();
  1032. sp1.swap(sp2);
  1033. REQUIRE(sp1.get() == ptr2);
  1034. REQUIRE(sp2.get() == ptr1);
  1035. swap(sp1, sp2);
  1036. REQUIRE(sp1.get() == ptr1);
  1037. REQUIRE(sp2.get() == ptr2);
  1038. REQUIRE((ptr1 == ptr2) == (sp1 == sp2));
  1039. REQUIRE((ptr1 != ptr2) == (sp1 != sp2));
  1040. REQUIRE((ptr1 < ptr2) == (sp1 < sp2));
  1041. REQUIRE((ptr1 <= ptr2) == (sp1 <= sp2));
  1042. REQUIRE((ptr1 > ptr2) == (sp1 > sp2));
  1043. REQUIRE((ptr1 >= ptr2) == (sp1 >= sp2));
  1044. // construction
  1045. wil::weak_handle wh;
  1046. REQUIRE_FALSE(wh.lock());
  1047. wil::weak_handle wh1 = sp1;
  1048. REQUIRE(wh1.lock());
  1049. REQUIRE(wh1.lock().get() == ptr1);
  1050. wil::weak_handle wh1copy = wh1;
  1051. REQUIRE(wh1copy.lock());
  1052. // assignment
  1053. wh = wh1;
  1054. REQUIRE(wh.lock().get() == ptr1);
  1055. wh = sp2;
  1056. REQUIRE(wh.lock().get() == ptr2);
  1057. // reset
  1058. wh.reset();
  1059. REQUIRE_FALSE(wh.lock());
  1060. // expiration
  1061. wh = sp1;
  1062. sp1.reset();
  1063. REQUIRE(wh.expired());
  1064. REQUIRE_FALSE(wh.lock());
  1065. // swap
  1066. wh1 = sp1;
  1067. wil::weak_handle wh2 = sp2;
  1068. ptr1 = sp1.get();
  1069. ptr2 = sp2.get();
  1070. REQUIRE(wh1.lock().get() == ptr1);
  1071. REQUIRE(wh2.lock().get() == ptr2);
  1072. wh1.swap(wh2);
  1073. REQUIRE(wh1.lock().get() == ptr2);
  1074. REQUIRE(wh2.lock().get() == ptr1);
  1075. swap(wh1, wh2);
  1076. REQUIRE(wh1.lock().get() == ptr1);
  1077. REQUIRE(wh2.lock().get() == ptr2);
  1078. // put
  1079. sp1.reset(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  1080. REQUIRE(sp1);
  1081. sp1.put(); // frees the pointer...
  1082. REQUIRE_FALSE(sp1);
  1083. sp2 = sp1;
  1084. REQUIRE_FALSE(sp2);
  1085. *sp1.put() = ::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0);
  1086. REQUIRE(sp1);
  1087. REQUIRE_FALSE(sp2);
  1088. // address
  1089. sp1.reset(::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0));
  1090. REQUIRE(sp1);
  1091. &sp1; // frees the pointer...
  1092. REQUIRE_FALSE(sp1);
  1093. sp2 = sp1;
  1094. REQUIRE_FALSE(sp2);
  1095. *(&sp1) = ::CreateEventEx(nullptr, nullptr, CREATE_EVENT_INITIAL_SET, 0);
  1096. REQUIRE(sp1);
  1097. REQUIRE_FALSE(sp2);
  1098. // test stl container use (hash & std::less)
  1099. std::unordered_set<wil::shared_handle> hashSet;
  1100. hashSet.insert(sp1);
  1101. hashSet.insert(sp2);
  1102. std::set<wil::shared_handle> set;
  1103. set.insert(sp1);
  1104. set.insert(sp2);
  1105. }
  1106. #endif
  1107. template <typename event_t>
  1108. void EventTestCommon()
  1109. {
  1110. // Constructor tests...
  1111. event_t e1;
  1112. REQUIRE_FALSE(e1);
  1113. event_t e2(::CreateEventEx(nullptr, nullptr, 0, 0));
  1114. REQUIRE(e2);
  1115. wil::unique_handle h1(::CreateEventEx(nullptr, nullptr, 0, 0));
  1116. REQUIRE(h1);
  1117. event_t e3(h1.release());
  1118. REQUIRE(e3);
  1119. REQUIRE_FALSE(h1);
  1120. event_t e4(std::move(e2));
  1121. REQUIRE(e4);
  1122. REQUIRE_FALSE(e2);
  1123. // inherited address tests...
  1124. REQUIRE(e4);
  1125. &e4;
  1126. REQUIRE_FALSE(e4);
  1127. auto hFill = ::CreateEventEx(nullptr, nullptr, 0, 0);
  1128. *(&e4) = hFill;
  1129. REQUIRE(e4);
  1130. REQUIRE(*e4.addressof() == hFill);
  1131. REQUIRE(e4);
  1132. // assignment...
  1133. event_t e5;
  1134. e5 = std::move(e4);
  1135. REQUIRE(e5);
  1136. REQUIRE_FALSE(e4);
  1137. // various event-based tests
  1138. event_t eManual;
  1139. eManual.create(wil::EventOptions::ManualReset);
  1140. REQUIRE_FALSE(eManual.is_signaled());
  1141. eManual.SetEvent();
  1142. REQUIRE(eManual.is_signaled());
  1143. eManual.ResetEvent();
  1144. REQUIRE_FALSE(eManual.is_signaled());
  1145. {
  1146. auto exit = eManual.SetEvent_scope_exit();
  1147. REQUIRE_FALSE(eManual.is_signaled());
  1148. }
  1149. REQUIRE(eManual.is_signaled());
  1150. {
  1151. auto exit = eManual.ResetEvent_scope_exit();
  1152. REQUIRE(eManual.is_signaled());
  1153. }
  1154. REQUIRE_FALSE(eManual.is_signaled());
  1155. REQUIRE_FALSE(eManual.wait(50));
  1156. REQUIRE_FALSE(wil::handle_wait(eManual.get(), 50));
  1157. eManual.SetEvent();
  1158. REQUIRE(eManual.wait(50));
  1159. REQUIRE(wil::handle_wait(eManual.get(), 50));
  1160. REQUIRE(eManual.wait(50));
  1161. REQUIRE(eManual.try_create(wil::EventOptions::ManualReset, L"IExist"));
  1162. REQUIRE_FALSE(eManual.try_open(L"IDontExist"));
  1163. }
  1164. template <typename mutex_t>
  1165. void MutexTestCommon()
  1166. {
  1167. // Constructor tests...
  1168. mutex_t m1;
  1169. REQUIRE_FALSE(m1);
  1170. mutex_t m2(::CreateMutexEx(nullptr, nullptr, 0, 0));
  1171. REQUIRE(m2);
  1172. wil::unique_handle h1(::CreateMutexEx(nullptr, nullptr, 0, 0));
  1173. REQUIRE(h1);
  1174. mutex_t m3(h1.release());
  1175. REQUIRE(m3);
  1176. REQUIRE_FALSE(h1);
  1177. mutex_t m4(std::move(m2));
  1178. REQUIRE(m4);
  1179. REQUIRE_FALSE(m2);
  1180. // inherited address tests...
  1181. REQUIRE(m4);
  1182. &m4;
  1183. REQUIRE_FALSE(m4);
  1184. auto hFill = ::CreateMutexEx(nullptr, nullptr, 0, 0);
  1185. *(&m4) = hFill;
  1186. REQUIRE(m4);
  1187. REQUIRE(*m4.addressof() == hFill);
  1188. REQUIRE(m4);
  1189. // assignment...
  1190. mutex_t m5;
  1191. m5 = std::move(m4);
  1192. REQUIRE(m5);
  1193. REQUIRE_FALSE(m4);
  1194. // various mutex-based tests
  1195. mutex_t eManual;
  1196. eManual.create(nullptr, CREATE_MUTEX_INITIAL_OWNER);
  1197. eManual.ReleaseMutex();
  1198. eManual.create(nullptr, CREATE_MUTEX_INITIAL_OWNER);
  1199. {
  1200. auto release = eManual.ReleaseMutex_scope_exit();
  1201. }
  1202. {
  1203. DWORD dwStatus;
  1204. auto release = eManual.acquire(&dwStatus);
  1205. REQUIRE(release);
  1206. REQUIRE(dwStatus == WAIT_OBJECT_0);
  1207. }
  1208. // pass-through methods -- test compilation;
  1209. REQUIRE(eManual.try_create(L"FOO-TEST"));
  1210. REQUIRE(eManual.try_open(L"FOO-TEST"));
  1211. }
  1212. template <typename semaphore_t>
  1213. void SemaphoreTestCommon()
  1214. {
  1215. // Constructor tests...
  1216. semaphore_t m1;
  1217. REQUIRE_FALSE(m1);
  1218. semaphore_t m2(::CreateSemaphoreEx(nullptr, 1, 1, nullptr, 0, 0));
  1219. REQUIRE(m2);
  1220. wil::unique_handle h1(::CreateSemaphoreEx(nullptr, 1, 1, nullptr, 0, 0));
  1221. REQUIRE(h1);
  1222. semaphore_t m3(h1.release());
  1223. REQUIRE(m3);
  1224. REQUIRE_FALSE(h1);
  1225. semaphore_t m4(std::move(m2));
  1226. REQUIRE(m4);
  1227. REQUIRE_FALSE(m2);
  1228. // inherited address tests...
  1229. REQUIRE(m4);
  1230. &m4;
  1231. REQUIRE_FALSE(m4);
  1232. auto hFill = ::CreateSemaphoreEx(nullptr, 1, 1, nullptr, 0, 0);
  1233. *(&m4) = hFill;
  1234. REQUIRE(m4);
  1235. REQUIRE(*m4.addressof() == hFill);
  1236. REQUIRE(m4);
  1237. // assignment...
  1238. semaphore_t m5;
  1239. m5 = std::move(m4);
  1240. REQUIRE(m5);
  1241. REQUIRE_FALSE(m4);
  1242. // various semaphore-based tests
  1243. semaphore_t eManual;
  1244. eManual.create(1, 1);
  1245. WaitForSingleObjectEx(eManual.get(), INFINITE, true);
  1246. eManual.ReleaseSemaphore();
  1247. eManual.create(1, 1);
  1248. WaitForSingleObjectEx(eManual.get(), INFINITE, true);
  1249. {
  1250. auto release = eManual.ReleaseSemaphore_scope_exit();
  1251. }
  1252. {
  1253. DWORD dwStatus;
  1254. auto release = eManual.acquire(&dwStatus);
  1255. REQUIRE(release);
  1256. REQUIRE(dwStatus == WAIT_OBJECT_0);
  1257. }
  1258. // pass-through methods -- test compilation;
  1259. REQUIRE(eManual.try_create(1, 1, L"BAR-TEST"));
  1260. REQUIRE(eManual.try_open(L"BAR-TEST"));
  1261. }
  1262. template <typename test_t>
  1263. void MutexRaiiTests()
  1264. {
  1265. test_t var1;
  1266. var1.create();
  1267. {
  1268. REQUIRE(var1.acquire());
  1269. }
  1270. // try_create
  1271. bool exists = false;
  1272. REQUIRE(var1.try_create(L"wiltestmutex", 0, MUTEX_ALL_ACCESS, nullptr, &exists));
  1273. REQUIRE_FALSE(exists);
  1274. test_t var2;
  1275. REQUIRE(var2.try_create(L"wiltestmutex", 0, MUTEX_ALL_ACCESS, nullptr, &exists));
  1276. REQUIRE(exists);
  1277. test_t var3;
  1278. REQUIRE_FALSE(var3.try_create(L"\\illegal\\chars\\too\\\\many\\\\namespaces", 0, MUTEX_ALL_ACCESS, nullptr, &exists));
  1279. REQUIRE(::GetLastError() != ERROR_SUCCESS);
  1280. // try_open
  1281. test_t var4;
  1282. REQUIRE_FALSE(var4.try_open(L"\\illegal\\chars\\too\\\\many\\\\namespaces"));
  1283. REQUIRE(::GetLastError() != ERROR_SUCCESS);
  1284. REQUIRE(var4.try_open(L"wiltestmutex"));
  1285. }
  1286. template <typename test_t>
  1287. void SemaphoreRaiiTests()
  1288. {
  1289. test_t var1;
  1290. var1.create(1, 1);
  1291. {
  1292. REQUIRE(var1.acquire());
  1293. }
  1294. // try_create
  1295. bool exists = false;
  1296. REQUIRE(var1.try_create(1, 1, L"wiltestsemaphore", MUTEX_ALL_ACCESS, nullptr, &exists));
  1297. REQUIRE_FALSE(exists);
  1298. test_t var2;
  1299. REQUIRE(var2.try_create(1, 1, L"wiltestsemaphore", MUTEX_ALL_ACCESS, nullptr, &exists));
  1300. REQUIRE(exists);
  1301. test_t var3;
  1302. REQUIRE_FALSE(var3.try_create(1, 1, L"\\illegal\\chars\\too\\\\many\\\\namespaces", MUTEX_ALL_ACCESS, nullptr, &exists));
  1303. REQUIRE(::GetLastError() != ERROR_SUCCESS);
  1304. // try_open
  1305. test_t var4;
  1306. REQUIRE_FALSE(var4.try_open(L"\\illegal\\chars\\too\\\\many\\\\namespaces"));
  1307. REQUIRE(::GetLastError() != ERROR_SUCCESS);
  1308. REQUIRE(var4.try_open(L"wiltestsemaphore"));
  1309. }
  1310. TEST_CASE("WindowsInternalTests::HandleWrappers", "[resource][unique_any]")
  1311. {
  1312. EventTestCommon<wil::unique_event_nothrow>();
  1313. EventTestCommon<wil::unique_event_failfast>();
  1314. // intentionally disabled in the non-exception version...
  1315. // wil::unique_event_nothrow testEvent2(wil::EventOptions::ManualReset);
  1316. wil::unique_event_failfast testEvent3(wil::EventOptions::ManualReset);
  1317. #ifdef WIL_ENABLE_EXCEPTIONS
  1318. EventTestCommon<wil::unique_event>();
  1319. wil::unique_event testEvent(wil::EventOptions::ManualReset);
  1320. {
  1321. REQUIRE_FALSE(wil::event_is_signaled(testEvent.get()));
  1322. auto eventSet = wil::SetEvent_scope_exit(testEvent.get());
  1323. REQUIRE_FALSE(wil::event_is_signaled(testEvent.get()));
  1324. }
  1325. {
  1326. REQUIRE(wil::event_is_signaled(testEvent.get()));
  1327. auto eventSet = wil::ResetEvent_scope_exit(testEvent.get());
  1328. REQUIRE(wil::event_is_signaled(testEvent.get()));
  1329. }
  1330. REQUIRE_FALSE(wil::event_is_signaled(testEvent.get()));
  1331. REQUIRE_FALSE(wil::handle_wait(testEvent.get(), 0));
  1332. // Exception-based - no return
  1333. testEvent.create(wil::EventOptions::ManualReset);
  1334. #endif
  1335. // Error-code based -- returns HR
  1336. wil::unique_event_nothrow testEventNoExcept;
  1337. REQUIRE(SUCCEEDED(testEventNoExcept.create(wil::EventOptions::ManualReset)));
  1338. MutexTestCommon<wil::unique_mutex_nothrow>();
  1339. MutexTestCommon<wil::unique_mutex_failfast>();
  1340. MutexRaiiTests<wil::unique_mutex_nothrow>();
  1341. MutexRaiiTests<wil::unique_mutex_failfast>();
  1342. // intentionally disabled in the non-exception version...
  1343. // wil::unique_mutex_nothrow testMutex2(L"FOO-TEST-2");
  1344. wil::unique_mutex_failfast testMutex3(L"FOO-TEST-3");
  1345. #ifdef WIL_ENABLE_EXCEPTIONS
  1346. MutexTestCommon<wil::unique_mutex>();
  1347. MutexRaiiTests<wil::unique_mutex>();
  1348. wil::unique_mutex testMutex(L"FOO-TEST");
  1349. WaitForSingleObjectEx(testMutex.get(), INFINITE, TRUE);
  1350. {
  1351. auto release = wil::ReleaseMutex_scope_exit(testMutex.get());
  1352. }
  1353. // Exception-based - no return
  1354. testMutex.create(nullptr);
  1355. #endif
  1356. // Error-code based -- returns HR
  1357. wil::unique_mutex_nothrow testMutexNoExcept;
  1358. REQUIRE(SUCCEEDED(testMutexNoExcept.create(nullptr)));
  1359. SemaphoreTestCommon<wil::unique_semaphore_nothrow>();
  1360. SemaphoreTestCommon<wil::unique_semaphore_failfast>();
  1361. SemaphoreRaiiTests<wil::unique_semaphore_nothrow>();
  1362. SemaphoreRaiiTests<wil::unique_semaphore_failfast>();
  1363. // intentionally disabled in the non-exception version...
  1364. // wil::unique_semaphore_nothrow testSemaphore2(1, 1);
  1365. wil::unique_semaphore_failfast testSemaphore3(1, 1);
  1366. #ifdef WIL_ENABLE_EXCEPTIONS
  1367. SemaphoreTestCommon<wil::unique_semaphore>();
  1368. SemaphoreRaiiTests<wil::unique_semaphore>();
  1369. wil::unique_semaphore testSemaphore(1, 1);
  1370. WaitForSingleObjectEx(testSemaphore.get(), INFINITE, true);
  1371. {
  1372. auto release = wil::ReleaseSemaphore_scope_exit(testSemaphore.get());
  1373. }
  1374. // Exception-based - no return
  1375. testSemaphore.create(1, 1);
  1376. #endif
  1377. // Error-code based -- returns HR
  1378. wil::unique_semaphore_nothrow testSemaphoreNoExcept;
  1379. REQUIRE(SUCCEEDED(testSemaphoreNoExcept.create(1, 1)));
  1380. auto unique_cotaskmem_string_failfast1 = wil::make_cotaskmem_string_failfast(L"Foo");
  1381. REQUIRE(wcscmp(L"Foo", unique_cotaskmem_string_failfast1.get()) == 0);
  1382. auto unique_cotaskmem_string_nothrow1 = wil::make_cotaskmem_string_nothrow(L"Foo");
  1383. REQUIRE(wcscmp(L"Foo", unique_cotaskmem_string_nothrow1.get()) == 0);
  1384. auto unique_cotaskmem_string_nothrow2 = wil::make_cotaskmem_string_nothrow(L"");
  1385. REQUIRE(wcscmp(L"", unique_cotaskmem_string_nothrow2.get()) == 0);
  1386. #ifdef WIL_ENABLE_EXCEPTIONS
  1387. auto unique_cotaskmem_string_te1 = wil::make_cotaskmem_string(L"Foo");
  1388. REQUIRE(wcscmp(L"Foo", unique_cotaskmem_string_te1.get()) == 0);
  1389. auto unique_cotaskmem_string_te2 = wil::make_cotaskmem_string(L"");
  1390. REQUIRE(wcscmp(L"", unique_cotaskmem_string_te2.get()) == 0);
  1391. auto unique_cotaskmem_string_range1 = wil::make_cotaskmem_string(L"Foo", 2);
  1392. REQUIRE(wcscmp(L"Fo", unique_cotaskmem_string_range1.get()) == 0);
  1393. auto unique_cotaskmem_string_range2 = wil::make_cotaskmem_string(nullptr, 2);
  1394. unique_cotaskmem_string_range2.get()[0] = L'F';
  1395. unique_cotaskmem_string_range2.get()[1] = L'o';
  1396. REQUIRE(wcscmp(L"Fo", unique_cotaskmem_string_range2.get()) == 0);
  1397. auto unique_cotaskmem_string_range3 = wil::make_cotaskmem_string(nullptr, 0);
  1398. REQUIRE(wcscmp(L"", unique_cotaskmem_string_range3.get()) == 0);
  1399. #endif
  1400. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  1401. {
  1402. auto verify = MakeSecureDeleterMallocSpy();
  1403. REQUIRE_SUCCEEDED(::CoRegisterMallocSpy(verify.Get()));
  1404. auto removeSpy = wil::scope_exit([&] { ::CoRevokeMallocSpy(); });
  1405. auto unique_cotaskmem_string_secure_failfast1 = wil::make_cotaskmem_string_secure_failfast(L"Foo");
  1406. REQUIRE(wcscmp(L"Foo", unique_cotaskmem_string_secure_failfast1.get()) == 0);
  1407. auto unique_cotaskmem_string_secure_nothrow1 = wil::make_cotaskmem_string_secure_nothrow(L"Foo");
  1408. REQUIRE(wcscmp(L"Foo", unique_cotaskmem_string_secure_nothrow1.get()) == 0);
  1409. auto unique_cotaskmem_string_secure_nothrow2 = wil::make_cotaskmem_string_secure_nothrow(L"");
  1410. REQUIRE(wcscmp(L"", unique_cotaskmem_string_secure_nothrow2.get()) == 0);
  1411. #ifdef WIL_ENABLE_EXCEPTIONS
  1412. auto unique_cotaskmem_string_secure_te1 = wil::make_cotaskmem_string_secure(L"Foo");
  1413. REQUIRE(wcscmp(L"Foo", unique_cotaskmem_string_secure_te1.get()) == 0);
  1414. auto unique_cotaskmem_string_secure_te2 = wil::make_cotaskmem_string_secure(L"");
  1415. REQUIRE(wcscmp(L"", unique_cotaskmem_string_secure_te2.get()) == 0);
  1416. #endif
  1417. }
  1418. auto unique_hlocal_string_failfast1 = wil::make_hlocal_string_failfast(L"Foo");
  1419. REQUIRE(wcscmp(L"Foo", unique_hlocal_string_failfast1.get()) == 0);
  1420. auto unique_hlocal_string_nothrow1 = wil::make_hlocal_string_nothrow(L"Foo");
  1421. REQUIRE(wcscmp(L"Foo", unique_hlocal_string_nothrow1.get()) == 0);
  1422. auto unique_hlocal_string_nothrow2 = wil::make_hlocal_string_nothrow(L"");
  1423. REQUIRE(wcscmp(L"", unique_hlocal_string_nothrow2.get()) == 0);
  1424. auto unique_hlocal_ansistring_failfast1 = wil::make_hlocal_ansistring_failfast("Foo");
  1425. REQUIRE(strcmp("Foo", unique_hlocal_ansistring_failfast1.get()) == 0);
  1426. auto unique_hlocal_ansistring_nothrow1 = wil::make_hlocal_ansistring_nothrow("Foo");
  1427. REQUIRE(strcmp("Foo", unique_hlocal_ansistring_nothrow1.get()) == 0);
  1428. auto unique_hlocal_ansistring_nothrow2 = wil::make_hlocal_ansistring_nothrow("");
  1429. REQUIRE(strcmp("", unique_hlocal_ansistring_nothrow2.get()) == 0);
  1430. #ifdef WIL_ENABLE_EXCEPTIONS
  1431. auto unique_hlocal_string_te1 = wil::make_hlocal_string(L"Foo");
  1432. REQUIRE(wcscmp(L"Foo", unique_hlocal_string_te1.get()) == 0);
  1433. auto unique_hlocal_string_te2 = wil::make_hlocal_string(L"");
  1434. REQUIRE(wcscmp(L"", unique_hlocal_string_te2.get()) == 0);
  1435. auto unique_hlocal_string_range1 = wil::make_hlocal_string(L"Foo", 2);
  1436. REQUIRE(wcscmp(L"Fo", unique_hlocal_string_range1.get()) == 0);
  1437. auto unique_hlocal_string_range2 = wil::make_hlocal_string(nullptr, 2);
  1438. unique_hlocal_string_range2.get()[0] = L'F';
  1439. unique_hlocal_string_range2.get()[1] = L'o';
  1440. REQUIRE(wcscmp(L"Fo", unique_hlocal_string_range2.get()) == 0);
  1441. auto unique_hlocal_string_range3 = wil::make_hlocal_string(nullptr, 0);
  1442. REQUIRE(wcscmp(L"", unique_hlocal_string_range3.get()) == 0);
  1443. auto unique_hlocal_ansistring_te1 = wil::make_hlocal_ansistring("Foo");
  1444. REQUIRE(strcmp("Foo", unique_hlocal_ansistring_te1.get()) == 0);
  1445. auto unique_hlocal_ansistring_te2 = wil::make_hlocal_ansistring("");
  1446. REQUIRE(strcmp("", unique_hlocal_ansistring_te2.get()) == 0);
  1447. auto unique_hlocal_ansistring_range1 = wil::make_hlocal_ansistring("Foo", 2);
  1448. REQUIRE(strcmp("Fo", unique_hlocal_ansistring_range1.get()) == 0);
  1449. auto unique_hlocal_ansistring_range2 = wil::make_hlocal_ansistring(nullptr, 2);
  1450. unique_hlocal_ansistring_range2.get()[0] = L'F';
  1451. unique_hlocal_ansistring_range2.get()[1] = L'o';
  1452. REQUIRE(strcmp("Fo", unique_hlocal_ansistring_range2.get()) == 0);
  1453. auto unique_hlocal_ansistring_range3 = wil::make_hlocal_ansistring(nullptr, 0);
  1454. REQUIRE(strcmp("", unique_hlocal_ansistring_range3.get()) == 0);
  1455. #endif
  1456. {
  1457. auto verify = MakeSecureDeleterMallocSpy();
  1458. REQUIRE_SUCCEEDED(::CoRegisterMallocSpy(verify.Get()));
  1459. auto removeSpy = wil::scope_exit([&] { ::CoRevokeMallocSpy(); });
  1460. auto unique_hlocal_string_secure_failfast1 = wil::make_hlocal_string_secure_failfast(L"Foo");
  1461. REQUIRE(wcscmp(L"Foo", unique_hlocal_string_secure_failfast1.get()) == 0);
  1462. auto unique_hlocal_string_secure_nothrow1 = wil::make_hlocal_string_secure_nothrow(L"Foo");
  1463. REQUIRE(wcscmp(L"Foo", unique_hlocal_string_secure_nothrow1.get()) == 0);
  1464. auto unique_hlocal_string_secure_nothrow2 = wil::make_hlocal_string_secure_nothrow(L"");
  1465. REQUIRE(wcscmp(L"", unique_hlocal_string_secure_nothrow2.get()) == 0);
  1466. #ifdef WIL_ENABLE_EXCEPTIONS
  1467. auto unique_hlocal_string_secure_te1 = wil::make_hlocal_string_secure(L"Foo");
  1468. REQUIRE(wcscmp(L"Foo", unique_hlocal_string_secure_te1.get()) == 0);
  1469. auto unique_hlocal_string_secure_te2 = wil::make_hlocal_string_secure(L"");
  1470. REQUIRE(wcscmp(L"", unique_hlocal_string_secure_te2.get()) == 0);
  1471. #endif
  1472. }
  1473. auto unique_process_heap_string_failfast1 = wil::make_process_heap_string_failfast(L"Foo");
  1474. REQUIRE(wcscmp(L"Foo", unique_process_heap_string_failfast1.get()) == 0);
  1475. auto unique_process_heap_string_nothrow1 = wil::make_process_heap_string_nothrow(L"Foo");
  1476. REQUIRE(wcscmp(L"Foo", unique_process_heap_string_nothrow1.get()) == 0);
  1477. auto unique_process_heap_string_nothrow2 = wil::make_process_heap_string_nothrow(L"");
  1478. REQUIRE(wcscmp(L"", unique_process_heap_string_nothrow2.get()) == 0);
  1479. #ifdef WIL_ENABLE_EXCEPTIONS
  1480. auto unique_process_heap_string_te1 = wil::make_process_heap_string(L"Foo");
  1481. REQUIRE(wcscmp(L"Foo", unique_process_heap_string_te1.get()) == 0);
  1482. auto unique_process_heap_string_te2 = wil::make_process_heap_string(L"");
  1483. REQUIRE(wcscmp(L"", unique_process_heap_string_te2.get()) == 0);
  1484. auto unique_process_heap_string_range1 = wil::make_process_heap_string(L"Foo", 2);
  1485. REQUIRE(wcscmp(L"Fo", unique_process_heap_string_range1.get()) == 0);
  1486. auto unique_process_heap_string_range2 = wil::make_process_heap_string(nullptr, 2);
  1487. unique_process_heap_string_range2.get()[0] = L'F';
  1488. unique_process_heap_string_range2.get()[1] = L'o';
  1489. REQUIRE(wcscmp(L"Fo", unique_process_heap_string_range2.get()) == 0);
  1490. auto unique_process_heap_string_range3 = wil::make_process_heap_string(nullptr, 0);
  1491. REQUIRE(wcscmp(L"", unique_process_heap_string_range3.get()) == 0);
  1492. #endif
  1493. #endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
  1494. auto unique_bstr_failfast1 = wil::make_bstr_failfast(L"Foo");
  1495. REQUIRE(wcscmp(L"Foo", unique_bstr_failfast1.get()) == 0);
  1496. auto unique_bstr_nothrow1 = wil::make_bstr_nothrow(L"Foo");
  1497. REQUIRE(wcscmp(L"Foo", unique_bstr_nothrow1.get()) == 0);
  1498. auto unique_bstr_nothrow2 = wil::make_bstr_nothrow(L"");
  1499. REQUIRE(wcscmp(L"", unique_bstr_nothrow2.get()) == 0);
  1500. auto unique_variant_bstr_failfast1 = wil::make_variant_bstr_failfast(L"Foo");
  1501. REQUIRE(wcscmp(L"Foo", V_UNION(unique_variant_bstr_failfast1.addressof(), bstrVal)) == 0);
  1502. auto unique_variant_bstr_nothrow1 = wil::make_variant_bstr_nothrow(L"Foo");
  1503. REQUIRE(wcscmp(L"Foo", V_UNION(unique_variant_bstr_nothrow1.addressof(), bstrVal)) == 0);
  1504. auto unique_variant_bstr_nothrow2 = wil::make_variant_bstr_nothrow(L"");
  1505. REQUIRE(wcscmp(L"", V_UNION(unique_variant_bstr_nothrow2.addressof(), bstrVal)) == 0);
  1506. #ifdef WIL_ENABLE_EXCEPTIONS
  1507. auto unique_bstr_te1 = wil::make_bstr(L"Foo");
  1508. REQUIRE(wcscmp(L"Foo", unique_bstr_te1.get()) == 0);
  1509. auto unique_bstr_te2 = wil::make_bstr(L"");
  1510. REQUIRE(wcscmp(L"", unique_bstr_te2.get()) == 0);
  1511. auto unique_variant_bstr_te1 = wil::make_variant_bstr(L"Foo");
  1512. REQUIRE(wcscmp(L"Foo", V_UNION(unique_variant_bstr_te1.addressof(), bstrVal)) == 0);
  1513. auto unique_variant_bstr_te2 = wil::make_variant_bstr(L"");
  1514. REQUIRE(wcscmp(L"", V_UNION(unique_variant_bstr_te2.addressof(), bstrVal)) == 0);
  1515. auto testString = wil::make_cotaskmem_string(L"Foo");
  1516. {
  1517. auto cleanupMemory = wil::SecureZeroMemory_scope_exit(testString.get());
  1518. }
  1519. REQUIRE(0 == testString.get()[0]);
  1520. auto testString2 = wil::make_cotaskmem_string(L"Bar");
  1521. {
  1522. auto cleanupMemory = wil::SecureZeroMemory_scope_exit(testString2.get(), wcslen(testString2.get()) * sizeof(testString2.get()[0]));
  1523. }
  1524. REQUIRE(0 == testString2.get()[0]);
  1525. #endif
  1526. }
  1527. TEST_CASE("WindowsInternalTests::Locking", "[resource]")
  1528. {
  1529. {
  1530. SRWLOCK rwlock = SRWLOCK_INIT;
  1531. {
  1532. auto lock = wil::AcquireSRWLockExclusive(&rwlock);
  1533. REQUIRE(lock);
  1534. auto lockRecursive = wil::TryAcquireSRWLockExclusive(&rwlock);
  1535. REQUIRE_FALSE(lockRecursive);
  1536. auto lockRecursiveShared = wil::TryAcquireSRWLockShared(&rwlock);
  1537. REQUIRE_FALSE(lockRecursiveShared);
  1538. }
  1539. {
  1540. auto lock = wil::AcquireSRWLockShared(&rwlock);
  1541. REQUIRE(lock);
  1542. auto lockRecursive = wil::TryAcquireSRWLockShared(&rwlock);
  1543. REQUIRE(lockRecursive);
  1544. auto lockRecursiveExclusive = wil::TryAcquireSRWLockExclusive(&rwlock);
  1545. REQUIRE_FALSE(lockRecursiveExclusive);
  1546. }
  1547. {
  1548. auto lock = wil::TryAcquireSRWLockExclusive(&rwlock);
  1549. REQUIRE(lock);
  1550. }
  1551. {
  1552. auto lock = wil::TryAcquireSRWLockShared(&rwlock);
  1553. REQUIRE(lock);
  1554. }
  1555. }
  1556. {
  1557. wil::srwlock rwlock;
  1558. {
  1559. auto lock = rwlock.lock_exclusive();
  1560. REQUIRE(lock);
  1561. auto lockRecursive = rwlock.try_lock_exclusive();
  1562. REQUIRE_FALSE(lockRecursive);
  1563. auto lockRecursiveShared = rwlock.try_lock_shared();
  1564. REQUIRE_FALSE(lockRecursiveShared);
  1565. }
  1566. {
  1567. auto lock = rwlock.lock_shared();
  1568. REQUIRE(lock);
  1569. auto lockRecursive = rwlock.try_lock_shared();
  1570. REQUIRE(lockRecursive);
  1571. auto lockRecursiveExclusive = rwlock.try_lock_exclusive();
  1572. REQUIRE_FALSE(lockRecursiveExclusive);
  1573. }
  1574. {
  1575. auto lock = rwlock.try_lock_exclusive();
  1576. REQUIRE(lock);
  1577. }
  1578. {
  1579. auto lock = rwlock.try_lock_shared();
  1580. REQUIRE(lock);
  1581. }
  1582. }
  1583. {
  1584. CRITICAL_SECTION cs;
  1585. ::InitializeCriticalSectionEx(&cs, 0, 0);
  1586. {
  1587. auto lock = wil::EnterCriticalSection(&cs);
  1588. REQUIRE(lock);
  1589. auto tryLock = wil::TryEnterCriticalSection(&cs);
  1590. REQUIRE(tryLock);
  1591. }
  1592. ::DeleteCriticalSection(&cs);
  1593. }
  1594. {
  1595. wil::critical_section cs;
  1596. auto lock = cs.lock();
  1597. REQUIRE(lock);
  1598. auto tryLock = cs.try_lock();
  1599. REQUIRE(tryLock);
  1600. }
  1601. }
  1602. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  1603. TEST_CASE("WindowsInternalTests::GDIWrappers", "[resource]")
  1604. {
  1605. {
  1606. auto dc = wil::GetDC(::GetDesktopWindow());
  1607. }
  1608. {
  1609. auto dc = wil::GetWindowDC(::GetDesktopWindow());
  1610. }
  1611. {
  1612. auto dc = wil::BeginPaint(::GetDesktopWindow());
  1613. wil::unique_hbrush brush(::CreateSolidBrush(0xffffff));
  1614. auto select = wil::SelectObject(dc.get(), brush.get());
  1615. }
  1616. }
  1617. #endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
  1618. void TestOutHandle(_Out_ HANDLE *pHandle)
  1619. {
  1620. *pHandle = nullptr;
  1621. }
  1622. void TestOutAlloc(_Out_ int **ppInt)
  1623. {
  1624. *ppInt = new int(5);
  1625. }
  1626. void TestCoTask(_Outptr_result_buffer_(*charCount) PWSTR *ppsz, size_t *charCount)
  1627. {
  1628. *charCount = 0;
  1629. PWSTR psz = static_cast<PWSTR>(::CoTaskMemAlloc(10));
  1630. if (psz != nullptr)
  1631. {
  1632. *charCount = 5;
  1633. *psz = L'\0';
  1634. }
  1635. *ppsz = psz;
  1636. }
  1637. void TestVoid(_Out_ void **ppv)
  1638. {
  1639. *ppv = nullptr;
  1640. }
  1641. void TestByte(_Out_ BYTE **ppByte)
  1642. {
  1643. *ppByte = nullptr;
  1644. }
  1645. struct my_deleter
  1646. {
  1647. template <typename T>
  1648. void operator()(T* p) const
  1649. {
  1650. delete p;
  1651. }
  1652. };
  1653. TEST_CASE("WindowsInternalTests::WistdTests", "[resource][wistd]")
  1654. {
  1655. wil::unique_handle spHandle;
  1656. TestOutHandle(wil::out_param(spHandle));
  1657. wistd::unique_ptr<int> spInt;
  1658. TestOutAlloc(wil::out_param(spInt));
  1659. std::unique_ptr<int> spIntStd;
  1660. TestOutAlloc(wil::out_param(spIntStd));
  1661. wil::unique_cotaskmem_string spsz0;
  1662. size_t count;
  1663. TestCoTask(wil::out_param(spsz0), &count);
  1664. std::unique_ptr<wchar_t[], wil::cotaskmem_deleter> spsz1;
  1665. TestCoTask(wil::out_param(spsz1), &count);
  1666. wistd::unique_ptr<wchar_t[], wil::cotaskmem_deleter> spsz2;
  1667. TestCoTask(wil::out_param(spsz2), &count);
  1668. wil::unique_cotaskmem_ptr<wchar_t[]> spsz3;
  1669. TestCoTask(wil::out_param(spsz3), &count);
  1670. wil::unique_cotaskmem_ptr<void> spv;
  1671. TestVoid(wil::out_param(spv));
  1672. std::unique_ptr<int> spIntStd2;
  1673. TestByte(wil::out_param_ptr<BYTE**>(spIntStd2));
  1674. struct Nothing
  1675. {
  1676. int n;
  1677. Nothing(int param) : n(param) {}
  1678. void Method() {}
  1679. };
  1680. auto spff = wil::make_unique_failfast<Nothing>(3);
  1681. auto sp = wil::make_unique_nothrow<Nothing>(3);
  1682. REQUIRE(sp);
  1683. #ifdef WIL_ENABLE_EXCEPTIONS
  1684. THROW_IF_NULL_ALLOC(sp.get());
  1685. THROW_IF_NULL_ALLOC(sp);
  1686. #endif
  1687. sp->Method();
  1688. decltype(sp) sp2;
  1689. sp2 = wistd::move(sp);
  1690. sp2.get();
  1691. wistd::unique_ptr<int> spConstruct;
  1692. wistd::unique_ptr<int> spConstruct2 = nullptr;
  1693. spConstruct = nullptr;
  1694. wistd::unique_ptr<int> spConstruct3(new int(3));
  1695. my_deleter d;
  1696. wistd::unique_ptr<int, my_deleter> spConstruct4(new int(4), d);
  1697. wistd::unique_ptr<int, my_deleter> spConstruct5(new int(5), my_deleter());
  1698. wistd::unique_ptr<int> spConstruct6(wistd::unique_ptr<int>(new int(6)));
  1699. spConstruct = std::move(spConstruct2);
  1700. spConstruct.swap(spConstruct2);
  1701. REQUIRE(*spConstruct4 == 4);
  1702. spConstruct4.get();
  1703. if (spConstruct4)
  1704. {
  1705. }
  1706. spConstruct.reset();
  1707. spConstruct.release();
  1708. auto spTooBig = wil::make_unique_nothrow<int[]>(static_cast<size_t>(-1));
  1709. REQUIRE_FALSE(spTooBig);
  1710. // REQUIRE_FAILFAST_UNSPECIFIED([]{ auto spTooBigFF = wil::make_unique_failfast<int[]>(static_cast<size_t>(-1)); });
  1711. object_counter_state state;
  1712. count = 0;
  1713. {
  1714. object_counter c{ state };
  1715. REQUIRE(state.instance_count() == 1);
  1716. wistd::function<void(int)> fn = [&count, c](int param)
  1717. {
  1718. count += param;
  1719. };
  1720. REQUIRE(state.instance_count() == 2);
  1721. fn(3);
  1722. REQUIRE(count == 3);
  1723. }
  1724. REQUIRE(state.instance_count() == 0);
  1725. count = 0;
  1726. {
  1727. wistd::function<void(int)> fn;
  1728. {
  1729. object_counter c{ state };
  1730. REQUIRE(state.instance_count() == 1);
  1731. fn = [&count, c](int param)
  1732. {
  1733. count += param;
  1734. };
  1735. REQUIRE(state.instance_count() == 2);
  1736. }
  1737. REQUIRE(state.instance_count() == 1);
  1738. fn(3);
  1739. REQUIRE(count == 3);
  1740. }
  1741. {
  1742. // Size Check -- the current implementation allows for 10 pointers to be passed through the lambda
  1743. int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12;
  1744. (void)a11; (void)a12;
  1745. wistd::function<void()> fn = [&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10]()
  1746. {
  1747. (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; (void)a6; (void)a7; (void)a8; (void)a9; (void)a10;
  1748. };
  1749. auto fnCopy = fn;
  1750. // Uncomment to double-check static assert. Reports:
  1751. // "The sizeof(wistd::function) has grown too large for the reserved buffer (10 pointers). Refactor to reduce size of the capture."
  1752. // wistd::function<void()> fn2 = [&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11]()
  1753. // {
  1754. // a1; a2; a3; a4; a5; a6; a7; a8; a9; a10; a11;
  1755. // };
  1756. }
  1757. }
  1758. template <typename test_t, typename lambda_t>
  1759. void NullptrRaiiTests(lambda_t const &fnCreate)
  1760. {
  1761. // nullptr_t construct
  1762. test_t var1 = nullptr; // implicit
  1763. REQUIRE_FALSE(var1);
  1764. test_t var2(nullptr); // explicit
  1765. REQUIRE_FALSE(var2);
  1766. // nullptr_t assingment
  1767. var1.reset(fnCreate());
  1768. REQUIRE(var1);
  1769. var1 = nullptr;
  1770. REQUIRE_FALSE(var1);
  1771. // nullptr_t reset
  1772. var1.reset(fnCreate());
  1773. REQUIRE(var1);
  1774. var1.reset(nullptr);
  1775. REQUIRE_FALSE(var1);
  1776. }
  1777. template <typename test_t, typename lambda_t>
  1778. void ReleaseRaiiTests(lambda_t const &fnCreate)
  1779. {
  1780. test_t var1(fnCreate());
  1781. REQUIRE(var1);
  1782. auto ptr = var1.release();
  1783. REQUIRE_FALSE(var1);
  1784. REQUIRE(ptr != test_t::policy::invalid_value());
  1785. REQUIRE(var1.get() == test_t::policy::invalid_value());
  1786. var1.reset(ptr);
  1787. }
  1788. template <typename test_t, typename lambda_t>
  1789. void GetRaiiTests(lambda_t const &fnCreate)
  1790. {
  1791. test_t var1;
  1792. REQUIRE_FALSE(var1);
  1793. REQUIRE(var1.get() == test_t::policy::invalid_value());
  1794. var1.reset(fnCreate());
  1795. REQUIRE(var1);
  1796. REQUIRE(var1.get() != test_t::policy::invalid_value());
  1797. }
  1798. template <typename test_t, typename lambda_t>
  1799. void SharedRaiiTests(lambda_t const &fnCreate)
  1800. {
  1801. // copy construction
  1802. test_t var1(fnCreate());
  1803. REQUIRE(var1);
  1804. test_t var2 = var1; // implicit
  1805. REQUIRE(var1);
  1806. REQUIRE(var2);
  1807. test_t var3(var1); // explicit
  1808. // copy assignment
  1809. test_t var4(fnCreate());
  1810. test_t var5;
  1811. var5 = var4;
  1812. REQUIRE(var5);
  1813. REQUIRE(var4);
  1814. // r-value construction from unique_ptr
  1815. typename test_t::unique_t unique1(fnCreate());
  1816. test_t var7(std::move(unique1)); // explicit
  1817. REQUIRE(var7);
  1818. REQUIRE_FALSE(unique1);
  1819. typename test_t::unique_t unique2(fnCreate());
  1820. test_t var8 = std::move(unique2); // implicit
  1821. REQUIRE(var8);
  1822. REQUIRE_FALSE(unique2);
  1823. // r-value assignment from unique_ptr
  1824. var8.reset();
  1825. REQUIRE_FALSE(var8);
  1826. unique2.reset(fnCreate());
  1827. var8 = std::move(unique2);
  1828. REQUIRE(var8);
  1829. REQUIRE_FALSE(unique2);
  1830. // use_count()
  1831. REQUIRE(var8.use_count() == 1);
  1832. auto var9 = var8;
  1833. REQUIRE(var8.use_count() == 2);
  1834. }
  1835. template <typename test_t, typename lambda_t>
  1836. void WeakRaiiTests(lambda_t const &fnCreate)
  1837. {
  1838. typedef typename test_t::shared_t shared_type;
  1839. // base constructor
  1840. test_t weak1;
  1841. // construct from shared
  1842. shared_type shared1(fnCreate());
  1843. test_t weak2 = shared1; // implicit
  1844. test_t weak3(shared1); // explicit
  1845. // construct from weak
  1846. test_t weak4 = weak2; // implicit
  1847. test_t weak5(weak2); // explicit
  1848. // assign from weak
  1849. weak2 = weak5;
  1850. // assign from shared
  1851. weak2 = shared1;
  1852. // reset
  1853. weak2.reset();
  1854. REQUIRE_FALSE(weak2.lock());
  1855. // swap
  1856. test_t swap1 = shared1;
  1857. test_t swap2;
  1858. REQUIRE(swap1.lock());
  1859. REQUIRE_FALSE(swap2.lock());
  1860. swap1.swap(swap2);
  1861. REQUIRE_FALSE(swap1.lock());
  1862. REQUIRE(swap2.lock());
  1863. // expired
  1864. REQUIRE_FALSE(swap2.expired());
  1865. shared1.reset();
  1866. REQUIRE(swap2.expired());
  1867. // lock
  1868. shared1.reset(fnCreate());
  1869. weak1 = shared1;
  1870. auto shared2 = weak1.lock();
  1871. REQUIRE(shared2);
  1872. shared2.reset();
  1873. REQUIRE(weak1.lock());
  1874. shared1.reset();
  1875. shared2 = weak1.lock();
  1876. REQUIRE_FALSE(shared2);
  1877. }
  1878. template <typename test_t, typename lambda_t>
  1879. void AddressRaiiTests(lambda_t const &fnCreate)
  1880. {
  1881. test_t var1(fnCreate());
  1882. REQUIRE(var1);
  1883. &var1;
  1884. REQUIRE_FALSE(var1); // the address operator does an auto-release
  1885. *(&var1) = fnCreate();
  1886. REQUIRE(var1);
  1887. var1.put();
  1888. REQUIRE_FALSE(var1); // verify that 'put()' does an auto-release
  1889. *var1.put() = fnCreate();
  1890. REQUIRE(var1);
  1891. REQUIRE(var1.addressof() != nullptr);
  1892. REQUIRE(var1); // verify that 'addressof()' does not auto-release
  1893. }
  1894. template <typename test_t, typename lambda_t>
  1895. void BasicRaiiTests(lambda_t const &fnCreate)
  1896. {
  1897. auto invalidHandle = test_t::policy::invalid_value();
  1898. // no-constructor construction
  1899. test_t var1;
  1900. REQUIRE_FALSE(var1);
  1901. // construct from a given resource
  1902. test_t var2(fnCreate()); // r-value
  1903. REQUIRE(var2);
  1904. test_t var3(invalidHandle); // l-value
  1905. REQUIRE_FALSE(var3);
  1906. // r-value construct from the same type
  1907. test_t var4(std::move(var2)); // explicit
  1908. REQUIRE(var4);
  1909. REQUIRE_FALSE(var2);
  1910. test_t varMove(fnCreate());
  1911. test_t var4implicit = std::move(varMove); // implicit
  1912. REQUIRE(var4implicit);
  1913. // move assignment
  1914. var2 = std::move(var4);
  1915. REQUIRE(var2);
  1916. REQUIRE_FALSE(var4);
  1917. // swap
  1918. var2.swap(var4);
  1919. REQUIRE(var4);
  1920. REQUIRE_FALSE(var2);
  1921. // explicit bool cast
  1922. REQUIRE(static_cast<bool>(var4));
  1923. REQUIRE_FALSE(static_cast<bool>(var2));
  1924. // reset
  1925. var4.reset();
  1926. REQUIRE_FALSE(var4);
  1927. var4.reset(fnCreate()); // r-value
  1928. REQUIRE(var4);
  1929. var4.reset(invalidHandle); // l-value
  1930. REQUIRE_FALSE(var4);
  1931. }
  1932. template <typename test_t>
  1933. void EventRaiiTests()
  1934. {
  1935. test_t var1;
  1936. var1.create(wil::EventOptions::ManualReset);
  1937. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  1938. // SetEvent/ResetEvent
  1939. var1.SetEvent();
  1940. REQUIRE(wil::event_is_signaled(var1.get()));
  1941. var1.ResetEvent();
  1942. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  1943. // SetEvent/ResetEvent scope_exit
  1944. {
  1945. auto exit = var1.SetEvent_scope_exit();
  1946. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  1947. }
  1948. REQUIRE(wil::event_is_signaled(var1.get()));
  1949. {
  1950. auto exit = var1.ResetEvent_scope_exit();
  1951. REQUIRE(wil::event_is_signaled(var1.get()));
  1952. }
  1953. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  1954. // is_signaled
  1955. REQUIRE_FALSE(var1.is_signaled());
  1956. // wait
  1957. REQUIRE_FALSE(var1.wait(50));
  1958. // try_create
  1959. bool exists = false;
  1960. REQUIRE(var1.try_create(wil::EventOptions::ManualReset, L"wiltestevent", nullptr, &exists));
  1961. REQUIRE_FALSE(exists);
  1962. test_t var2;
  1963. REQUIRE(var2.try_create(wil::EventOptions::ManualReset, L"wiltestevent", nullptr, &exists));
  1964. REQUIRE(exists);
  1965. test_t var3;
  1966. REQUIRE_FALSE(var3.try_create(wil::EventOptions::ManualReset, L"\\illegal\\chars\\too\\\\many\\\\namespaces", nullptr, &exists));
  1967. REQUIRE(::GetLastError() != ERROR_SUCCESS);
  1968. // try_open
  1969. test_t var4;
  1970. REQUIRE_FALSE(var4.try_open(L"\\illegal\\chars\\too\\\\many\\\\namespaces"));
  1971. REQUIRE(::GetLastError() != ERROR_SUCCESS);
  1972. REQUIRE(var4.try_open(L"wiltestevent"));
  1973. }
  1974. void EventTests()
  1975. {
  1976. static_assert(sizeof(wil::unique_event_nothrow) == sizeof(HANDLE), "event_t should be sizeof(HANDLE) to allow for raw array utilization");
  1977. auto fnCreate = []() { return CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, 0); };
  1978. BasicRaiiTests<wil::unique_event_nothrow>(fnCreate);
  1979. NullptrRaiiTests<wil::unique_event_nothrow>(fnCreate);
  1980. GetRaiiTests<wil::unique_event_nothrow>(fnCreate);
  1981. ReleaseRaiiTests<wil::unique_event_nothrow>(fnCreate);
  1982. AddressRaiiTests<wil::unique_event_nothrow>(fnCreate);
  1983. EventRaiiTests<wil::unique_event_nothrow>();
  1984. BasicRaiiTests<wil::unique_event_failfast>(fnCreate);
  1985. NullptrRaiiTests<wil::unique_event_failfast>(fnCreate);
  1986. GetRaiiTests<wil::unique_event_failfast>(fnCreate);
  1987. ReleaseRaiiTests<wil::unique_event_failfast>(fnCreate);
  1988. AddressRaiiTests<wil::unique_event_failfast>(fnCreate);
  1989. EventRaiiTests<wil::unique_event_failfast>();
  1990. wil::unique_event_nothrow event4;
  1991. REQUIRE(S_OK == event4.create(wil::EventOptions::ManualReset));
  1992. REQUIRE(FAILED(event4.create(wil::EventOptions::ManualReset, L"\\illegal\\chars\\too\\\\many\\\\namespaces")));
  1993. #ifdef WIL_ENABLE_EXCEPTIONS
  1994. static_assert(sizeof(wil::unique_event) == sizeof(HANDLE), "event_t should be sizeof(HANDLE) to allow for raw array utilization");
  1995. BasicRaiiTests<wil::unique_event>(fnCreate);
  1996. NullptrRaiiTests<wil::unique_event>(fnCreate);
  1997. GetRaiiTests<wil::unique_event>(fnCreate);
  1998. ReleaseRaiiTests<wil::unique_event>(fnCreate);
  1999. AddressRaiiTests<wil::unique_event>(fnCreate);
  2000. EventRaiiTests<wil::unique_event>();
  2001. BasicRaiiTests<wil::shared_event>(fnCreate);
  2002. NullptrRaiiTests<wil::shared_event>(fnCreate);
  2003. GetRaiiTests<wil::shared_event>(fnCreate);
  2004. AddressRaiiTests<wil::shared_event>(fnCreate);
  2005. SharedRaiiTests<wil::shared_event>(fnCreate);
  2006. EventRaiiTests<wil::shared_event>();
  2007. WeakRaiiTests<wil::weak_event>(fnCreate);
  2008. // explicitly disabled
  2009. // wil::unique_event_nothrow event1(wil::EventOptions::ManualReset);
  2010. wil::unique_event event2(wil::EventOptions::ManualReset);
  2011. wil::shared_event event3(wil::EventOptions::ManualReset);
  2012. event2.create(wil::EventOptions::ManualReset);
  2013. REQUIRE(event2);
  2014. event3.create(wil::EventOptions::ManualReset);
  2015. REQUIRE(event3);
  2016. REQUIRE_THROWS(event2.create(wil::EventOptions::ManualReset, L"\\illegal\\chars\\too\\\\many\\\\namespaces") );
  2017. REQUIRE_THROWS(event3.create(wil::EventOptions::ManualReset, L"\\illegal\\chars\\too\\\\many\\\\namespaces") );
  2018. wil::unique_event var1(wil::EventOptions::ManualReset);
  2019. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  2020. {
  2021. auto autoset = wil::SetEvent_scope_exit(var1.get());
  2022. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  2023. REQUIRE(autoset.get() == var1.get());
  2024. // &autoset; // verified disabled
  2025. // autoset.addressof(); // verified disabled
  2026. }
  2027. REQUIRE(wil::event_is_signaled(var1.get()));
  2028. {
  2029. auto autoreset = wil::ResetEvent_scope_exit(var1.get());
  2030. REQUIRE(wil::event_is_signaled(var1.get()));
  2031. autoreset.reset();
  2032. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  2033. }
  2034. {
  2035. auto autoset = wil::SetEvent_scope_exit(var1.get());
  2036. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  2037. autoset.release();
  2038. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  2039. }
  2040. REQUIRE_FALSE(wil::event_is_signaled(var1.get()));
  2041. #endif
  2042. }
  2043. typedef wil::unique_struct<PROPVARIANT, decltype(&::PropVariantClear), ::PropVariantClear> unique_prop_variant_no_init;
  2044. void SetPropVariantValue(_In_ int intVal, _Out_ PROPVARIANT* ppropvar)
  2045. {
  2046. ppropvar->intVal = intVal;
  2047. ppropvar->vt = VT_INT;
  2048. }
  2049. template<typename T>
  2050. void TestUniquePropVariant()
  2051. {
  2052. {
  2053. wil::unique_prop_variant spPropVariant;
  2054. REQUIRE(spPropVariant.vt == VT_EMPTY);
  2055. }
  2056. // constructor test
  2057. {
  2058. PROPVARIANT propVariant;
  2059. SetPropVariantValue(12, &propVariant);
  2060. T spPropVariant(propVariant);
  2061. REQUIRE(((spPropVariant.intVal == 12) && (spPropVariant.vt == VT_INT)));
  2062. T spPropVariant2(wistd::move(propVariant));
  2063. REQUIRE(((spPropVariant2.intVal == 12) && (spPropVariant2.vt == VT_INT)));
  2064. //spPropVariant = propVariant; // deleted function
  2065. //spPropVariant = wistd::move(propVariant); // deleted function
  2066. //spPropVariant.swap(propVariant); //deleted function
  2067. }
  2068. // move constructor
  2069. {
  2070. T spPropVariant;
  2071. SetPropVariantValue(12, &spPropVariant);
  2072. REQUIRE(((spPropVariant.intVal == 12) && (spPropVariant.vt == VT_INT)));
  2073. T spPropVariant2(wistd::move(spPropVariant));
  2074. REQUIRE(spPropVariant.vt == VT_EMPTY);
  2075. REQUIRE(((spPropVariant2.intVal == 12) && (spPropVariant2.vt == VT_INT)));
  2076. //T spPropVariant3(spPropVariant); // deleted function
  2077. //spPropVariant2 = spPropVariant; // deleted function
  2078. }
  2079. // move operator
  2080. {
  2081. T spPropVariant;
  2082. SetPropVariantValue(12, &spPropVariant);
  2083. T spPropVariant2 = wistd::move(spPropVariant);
  2084. REQUIRE(spPropVariant.vt == VT_EMPTY);
  2085. REQUIRE(((spPropVariant2.intVal == 12) && (spPropVariant2.vt == VT_INT)));
  2086. }
  2087. // reset
  2088. {
  2089. PROPVARIANT propVariant;
  2090. SetPropVariantValue(22, &propVariant);
  2091. T spPropVariant;
  2092. SetPropVariantValue(12, &spPropVariant);
  2093. T spPropVariant2;
  2094. //spPropVariant2.reset(spPropVariant); // deleted function
  2095. spPropVariant.reset(propVariant);
  2096. REQUIRE(spPropVariant.intVal == 22);
  2097. REQUIRE(propVariant.intVal == 22);
  2098. spPropVariant.reset();
  2099. REQUIRE(spPropVariant.vt == VT_EMPTY);
  2100. }
  2101. // swap
  2102. {
  2103. T spPropVariant;
  2104. SetPropVariantValue(12, &spPropVariant);
  2105. T spPropVariant2;
  2106. SetPropVariantValue(22, &spPropVariant2);
  2107. spPropVariant.swap(spPropVariant2);
  2108. REQUIRE(spPropVariant.intVal == 22);
  2109. REQUIRE(spPropVariant2.intVal == 12);
  2110. }
  2111. // release, addressof, reset_and_addressof
  2112. {
  2113. T spPropVariant;
  2114. SetPropVariantValue(12, &spPropVariant);
  2115. [](PROPVARIANT* propVariant)
  2116. {
  2117. REQUIRE(propVariant->vt == VT_EMPTY);
  2118. }(spPropVariant.reset_and_addressof());
  2119. SetPropVariantValue(12, &spPropVariant);
  2120. PROPVARIANT* pPropVariant = spPropVariant.addressof();
  2121. REQUIRE(pPropVariant->intVal == 12);
  2122. REQUIRE(spPropVariant.intVal == 12);
  2123. PROPVARIANT propVariant = spPropVariant.release();
  2124. REQUIRE(propVariant.intVal == 12);
  2125. REQUIRE(spPropVariant.vt == VT_EMPTY);
  2126. }
  2127. }
  2128. TEST_CASE("WindowsInternalTests::ResourceTemplateTests", "[resource]")
  2129. {
  2130. EventTests();
  2131. TestUniquePropVariant<wil::unique_prop_variant>();
  2132. TestUniquePropVariant<unique_prop_variant_no_init>();
  2133. }
  2134. inline unsigned long long ToInt64(const FILETIME &ft)
  2135. {
  2136. return (static_cast<unsigned long long>(ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
  2137. }
  2138. inline FILETIME FromInt64(unsigned long long i64)
  2139. {
  2140. FILETIME ft = { static_cast<DWORD>(i64), static_cast<DWORD>(i64 >> 32) };
  2141. return ft;
  2142. }
  2143. TEST_CASE("WindowsInternalTests::Win32HelperTests", "[win32_helpers]")
  2144. {
  2145. auto systemTime = wil::filetime::get_system_time();
  2146. REQUIRE(ToInt64(systemTime) == wil::filetime::to_int64(systemTime));
  2147. auto systemTime64 = wil::filetime::to_int64(systemTime);
  2148. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  2149. auto ft1 = FromInt64(systemTime64);
  2150. auto ft2 = wil::filetime::from_int64(systemTime64);
  2151. REQUIRE(CompareFileTime(&ft1, &ft2) == 0);
  2152. #endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
  2153. REQUIRE(systemTime64 == wil::filetime::to_int64(wil::filetime::from_int64(systemTime64)));
  2154. REQUIRE((systemTime64 + wil::filetime_duration::one_hour) == (systemTime64 + (wil::filetime_duration::one_minute * 60)));
  2155. auto systemTimePlusOneHour = wil::filetime::add(systemTime, wil::filetime_duration::one_hour);
  2156. auto systemTimePlusOneHour64 = wil::filetime::to_int64(systemTimePlusOneHour);
  2157. REQUIRE(systemTimePlusOneHour64 == (systemTime64 + wil::filetime_duration::one_hour));
  2158. }
  2159. TEST_CASE("WindowsInternalTests::RectHelperTests", "[win32_helpers]")
  2160. {
  2161. RECT rect{ 50, 100, 200, 300 };
  2162. POINT leftEdgePoint{ 50, 150 };
  2163. POINT topEdgePoint{ 100, 100 };
  2164. POINT rightEdgePoint{ 200, 150 };
  2165. POINT bottomEdgePoint{ 100, 300 };
  2166. POINT insidePoint{ 150, 150};
  2167. RECT emptyRectAtOrigin{};
  2168. RECT emptyRectNotAtOrigin{ 50, 50, 50, 50 };
  2169. RECT nonNormalizedRect{ 300, 300, 0, 0 };
  2170. REQUIRE(wil::rect_width(rect) == 150);
  2171. REQUIRE(wil::rect_height(rect) == 200);
  2172. // rect_is_empty should work like user32's IsRectEmpty
  2173. REQUIRE_FALSE(wil::rect_is_empty(rect));
  2174. REQUIRE(wil::rect_is_empty(emptyRectAtOrigin));
  2175. REQUIRE(wil::rect_is_empty(emptyRectNotAtOrigin));
  2176. REQUIRE(wil::rect_is_empty(nonNormalizedRect));
  2177. // rect_contains_point should work like user32's PtInRect
  2178. REQUIRE(wil::rect_contains_point(rect, insidePoint));
  2179. REQUIRE(wil::rect_contains_point(rect, leftEdgePoint));
  2180. REQUIRE(wil::rect_contains_point(rect, topEdgePoint));
  2181. REQUIRE_FALSE(wil::rect_contains_point(rect, rightEdgePoint));
  2182. REQUIRE_FALSE(wil::rect_contains_point(rect, bottomEdgePoint));
  2183. REQUIRE_FALSE(wil::rect_contains_point(nonNormalizedRect, insidePoint));
  2184. auto rectFromSize = wil::rect_from_size<RECT>(50, 100, 150, 200);
  2185. REQUIRE(rectFromSize.left == rect.left);
  2186. REQUIRE(rectFromSize.top == rect.top);
  2187. REQUIRE(rectFromSize.right == rect.right);
  2188. REQUIRE(rectFromSize.bottom == rect.bottom);
  2189. }
  2190. TEST_CASE("WindowsInternalTests::InitOnceNonTests")
  2191. {
  2192. bool called = false;
  2193. bool winner = false;
  2194. INIT_ONCE init{};
  2195. REQUIRE_FALSE(wil::init_once_initialized(init));
  2196. // Call, but fail. Should transport the HRESULT back, but mark us as not the winner
  2197. called = false;
  2198. winner = false;
  2199. REQUIRE(E_FAIL == wil::init_once_nothrow(init, [&] { called = true; return E_FAIL; }, &winner));
  2200. REQUIRE_FALSE(wil::init_once_initialized(init));
  2201. REQUIRE(called);
  2202. REQUIRE_FALSE(winner);
  2203. // Call, succeed. Should mark us as the winner.
  2204. called = false;
  2205. winner = false;
  2206. REQUIRE_SUCCEEDED(wil::init_once_nothrow(init, [&] { called = true; return S_OK; }, &winner));
  2207. REQUIRE(wil::init_once_initialized(init));
  2208. REQUIRE(called);
  2209. REQUIRE(winner);
  2210. // Call again. Should not actually be invoked and should not be the winner
  2211. called = false;
  2212. winner = false;
  2213. REQUIRE_SUCCEEDED(wil::init_once_nothrow(init, [&] { called = false; return S_OK; }, &winner));
  2214. REQUIRE(wil::init_once_initialized(init));
  2215. REQUIRE_FALSE(called);
  2216. REQUIRE_FALSE(winner);
  2217. // Call again. Still not invoked, but we don't care if we're the winner
  2218. called = false;
  2219. REQUIRE_SUCCEEDED(wil::init_once_nothrow(init, [&] { called = false; return S_OK; }));
  2220. REQUIRE(wil::init_once_initialized(init));
  2221. REQUIRE_FALSE(called);
  2222. #ifdef WIL_ENABLE_EXCEPTIONS
  2223. called = false;
  2224. winner = false;
  2225. init = {};
  2226. // A thrown exception leaves the object un-initialized
  2227. static volatile bool always_true = true; // So that the compiler can't determine that we unconditionally throw below (warning C4702)
  2228. REQUIRE_THROWS_AS(winner = wil::init_once(init, [&] { called = true; THROW_HR_IF(E_FAIL, always_true); }), wil::ResultException);
  2229. REQUIRE_FALSE(wil::init_once_initialized(init));
  2230. REQUIRE(called);
  2231. REQUIRE_FALSE(winner);
  2232. // Success!
  2233. called = false;
  2234. winner = false;
  2235. REQUIRE_NOTHROW(winner = wil::init_once(init, [&] { called = true; }));
  2236. REQUIRE(wil::init_once_initialized(init));
  2237. REQUIRE(called);
  2238. REQUIRE(winner);
  2239. // No-op success!
  2240. called = false;
  2241. winner = false;
  2242. REQUIRE_NOTHROW(winner = wil::init_once(init, [&] { called = true; }));
  2243. REQUIRE(wil::init_once_initialized(init));
  2244. REQUIRE_FALSE(called);
  2245. REQUIRE_FALSE(winner);
  2246. #endif // WIL_ENABLE_EXCEPTIONS
  2247. }
  2248. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  2249. TEST_CASE("WindowsInternalTests::TestUniquePointerCases", "[resource][unique_any]")
  2250. {
  2251. // wil::unique_process_heap_ptr tests
  2252. {
  2253. wil::unique_process_heap_ptr<void> empty; // null case
  2254. }
  2255. {
  2256. wil::unique_process_heap_ptr<void> heapMemory(::HeapAlloc(::GetProcessHeap(), 0, 100));
  2257. REQUIRE(static_cast<bool>(heapMemory));
  2258. }
  2259. // wil::unique_cotaskmem_ptr tests
  2260. {
  2261. wil::unique_cotaskmem_ptr<void> empty; // null case
  2262. }
  2263. {
  2264. wil::unique_cotaskmem_ptr<void> cotaskmemMemory(CoTaskMemAlloc(100));
  2265. REQUIRE(static_cast<bool>(cotaskmemMemory));
  2266. }
  2267. {
  2268. auto cotaskmemMemory = wil::make_unique_cotaskmem_nothrow<DWORD>(42);
  2269. REQUIRE(static_cast<bool>(cotaskmemMemory));
  2270. REQUIRE(*cotaskmemMemory == static_cast<DWORD>(42));
  2271. }
  2272. {
  2273. struct S { size_t s; S() : s(42) {} };
  2274. auto cotaskmemMemory = wil::make_unique_cotaskmem_nothrow<S>();
  2275. REQUIRE(static_cast<bool>(cotaskmemMemory));
  2276. REQUIRE(cotaskmemMemory->s == static_cast<size_t>(42));
  2277. }
  2278. {
  2279. auto cotaskmemArrayMemory = wil::make_unique_cotaskmem_nothrow<BYTE[]>(12);
  2280. REQUIRE(static_cast<bool>(cotaskmemArrayMemory));
  2281. }
  2282. {
  2283. struct S { size_t s; S() : s(42) {} };
  2284. const size_t size = 12;
  2285. auto cotaskmemArrayMemory = wil::make_unique_cotaskmem_nothrow<S[]>(size);
  2286. REQUIRE(static_cast<bool>(cotaskmemArrayMemory));
  2287. bool verified = true;
  2288. for (auto& elem : wil::make_range(cotaskmemArrayMemory.get(), size)) if (elem.s != 42) verified = false;
  2289. REQUIRE(verified);
  2290. }
  2291. // wil::unique_cotaskmem_secure_ptr tests
  2292. {
  2293. wil::unique_cotaskmem_secure_ptr<void> empty; // null case
  2294. }
  2295. {
  2296. wil::unique_cotaskmem_secure_ptr<void> cotaskmemMemory(CoTaskMemAlloc(100));
  2297. REQUIRE(static_cast<bool>(cotaskmemMemory));
  2298. }
  2299. {
  2300. auto cotaskmemMemory = wil::make_unique_cotaskmem_secure_nothrow<DWORD>(42);
  2301. REQUIRE(static_cast<bool>(cotaskmemMemory));
  2302. REQUIRE(*cotaskmemMemory == static_cast<DWORD>(42));
  2303. }
  2304. {
  2305. struct S { size_t s; S() : s(42) {} };
  2306. auto cotaskmemMemory = wil::make_unique_cotaskmem_secure_nothrow<S>();
  2307. REQUIRE(static_cast<bool>(cotaskmemMemory));
  2308. REQUIRE(cotaskmemMemory->s == static_cast<size_t>(42));
  2309. }
  2310. {
  2311. auto cotaskmemArrayMemory = wil::make_unique_cotaskmem_secure_nothrow<BYTE[]>(12);
  2312. REQUIRE(static_cast<bool>(cotaskmemArrayMemory));
  2313. }
  2314. {
  2315. struct S { size_t s; S() : s(42) {} };
  2316. const size_t size = 12;
  2317. auto cotaskmemArrayMemory = wil::make_unique_cotaskmem_secure_nothrow<S[]>(size);
  2318. REQUIRE(static_cast<bool>(cotaskmemArrayMemory));
  2319. bool verified = true;
  2320. for (auto& elem : wil::make_range(cotaskmemArrayMemory.get(), size)) if (elem.s != 42) verified = false;
  2321. REQUIRE(verified);
  2322. }
  2323. // wil::unique_hlocal_ptr tests
  2324. {
  2325. wil::unique_hlocal_ptr<void> empty; // null case
  2326. }
  2327. {
  2328. wil::unique_hlocal_ptr<void> localMemory(LocalAlloc(LPTR, 100));
  2329. REQUIRE(static_cast<bool>(localMemory));
  2330. }
  2331. {
  2332. auto localMemory = wil::make_unique_hlocal_nothrow<DWORD>(42);
  2333. REQUIRE(static_cast<bool>(localMemory));
  2334. REQUIRE(*localMemory == static_cast<DWORD>(42));
  2335. }
  2336. {
  2337. struct S { size_t s; S() : s(42) {} };
  2338. auto localMemory = wil::make_unique_hlocal_nothrow<S>();
  2339. REQUIRE(static_cast<bool>(localMemory));
  2340. REQUIRE(localMemory->s == static_cast<size_t>(42));
  2341. }
  2342. {
  2343. auto localArrayMemory = wil::make_unique_hlocal_nothrow<BYTE[]>(12);
  2344. REQUIRE(static_cast<bool>(localArrayMemory));
  2345. }
  2346. {
  2347. struct S { size_t s; S() : s(42) {} };
  2348. const size_t size = 12;
  2349. auto localArrayMemory = wil::make_unique_hlocal_nothrow<S[]>(size);
  2350. REQUIRE(static_cast<bool>(localArrayMemory));
  2351. bool verified = true;
  2352. for (auto& elem : wil::make_range(localArrayMemory.get(), size)) if (elem.s != 42) verified = false;
  2353. REQUIRE(verified);
  2354. }
  2355. // wil::unique_hlocal_secure_ptr tests
  2356. {
  2357. wil::unique_hlocal_secure_ptr<void> empty; // null case
  2358. }
  2359. {
  2360. wil::unique_hlocal_secure_ptr<void> localMemory(LocalAlloc(LPTR, 100));
  2361. REQUIRE(static_cast<bool>(localMemory));
  2362. }
  2363. {
  2364. auto localMemory = wil::make_unique_hlocal_secure_nothrow<DWORD>(42);
  2365. REQUIRE(static_cast<bool>(localMemory));
  2366. REQUIRE(*localMemory == static_cast<DWORD>(42));
  2367. }
  2368. {
  2369. struct S { size_t s; S() : s(42) {} };
  2370. auto localMemory = wil::make_unique_hlocal_secure_nothrow<S>();
  2371. REQUIRE(static_cast<bool>(localMemory));
  2372. REQUIRE(localMemory->s == static_cast<size_t>(42));
  2373. }
  2374. {
  2375. auto localArrayMemory = wil::make_unique_hlocal_secure_nothrow<BYTE[]>(12);
  2376. REQUIRE(static_cast<bool>(localArrayMemory));
  2377. }
  2378. {
  2379. struct S { size_t s; S() : s(42) {} };
  2380. const size_t size = 12;
  2381. auto localArrayMemory = wil::make_unique_hlocal_secure_nothrow<S[]>(size);
  2382. REQUIRE(static_cast<bool>(localArrayMemory));
  2383. bool verified = true;
  2384. for (auto& elem : wil::make_range(localArrayMemory.get(), size)) if (elem.s != 42) verified = false;
  2385. REQUIRE(verified);
  2386. }
  2387. // wil::unique_hglobal_ptr tests
  2388. {
  2389. wil::unique_hglobal_ptr<void> empty; // null case
  2390. }
  2391. {
  2392. wil::unique_hglobal_ptr<void> globalMemory(GlobalAlloc(GPTR, 100));
  2393. REQUIRE(static_cast<bool>(globalMemory));
  2394. }
  2395. {
  2396. // The following uses are blocked due to a static assert failure
  2397. //struct S { ~S() {} };
  2398. //auto cotaskmemMemory = wil::make_unique_cotaskmem_nothrow<S>();
  2399. //auto cotaskmemArrayMemory = wil::make_unique_cotaskmem_nothrow<S[]>(1);
  2400. //auto cotaskmemMemory2 = wil::make_unique_cotaskmem_secure_nothrow<S>();
  2401. //auto cotaskmemArrayMemory2 = wil::make_unique_cotaskmem_secure_nothrow<S[]>(1);
  2402. //auto localMemory = wil::make_unique_hlocal_nothrow<S>();
  2403. //auto localArrayMemory = wil::make_unique_hlocal_nothrow<S[]>(1);
  2404. //auto localMemory2 = wil::make_unique_hlocal_secure_nothrow<S>();
  2405. //auto localArrayMemory2 = wil::make_unique_hlocal_secure_nothrow<S[]>(1);
  2406. }
  2407. }
  2408. #endif
  2409. void GetDWORDArray(_Out_ size_t* count, _Outptr_result_buffer_(*count) DWORD** numbers)
  2410. {
  2411. const size_t size = 5;
  2412. auto ptr = static_cast<DWORD*>(::CoTaskMemAlloc(sizeof(DWORD) * size));
  2413. REQUIRE(ptr);
  2414. ::ZeroMemory(ptr, sizeof(DWORD) * size);
  2415. *numbers = ptr;
  2416. *count = size;
  2417. }
  2418. void GetHSTRINGArray(_Out_ ULONG* count, _Outptr_result_buffer_(*count) HSTRING** strings)
  2419. {
  2420. const size_t size = 5;
  2421. auto ptr = static_cast<HSTRING*>(::CoTaskMemAlloc(sizeof(HSTRING) * size));
  2422. REQUIRE(ptr);
  2423. for (UINT i = 0; i < size; ++i)
  2424. {
  2425. REQUIRE_SUCCEEDED(WindowsCreateString(L"test", static_cast<UINT32>(wcslen(L"test")), &ptr[i]));
  2426. }
  2427. *strings = ptr;
  2428. *count = static_cast<ULONG>(size);
  2429. }
  2430. void GetPOINTArray(_Out_ UINT32* count, _Outptr_result_buffer_(*count) POINT** points)
  2431. {
  2432. const size_t size = 5;
  2433. auto ptr = static_cast<POINT*>(::CoTaskMemAlloc(sizeof(POINT) * size));
  2434. REQUIRE(ptr);
  2435. for (UINT i = 0; i < size; ++i)
  2436. {
  2437. ptr[i].x = ptr[i].y = i;
  2438. }
  2439. *points = ptr;
  2440. *count = static_cast<UINT32>(size);
  2441. }
  2442. #ifdef WIL_ENABLE_EXCEPTIONS
  2443. void GetHANDLEArray(_Out_ size_t* count, _Outptr_result_buffer_(*count) HANDLE** events)
  2444. {
  2445. const size_t size = 5;
  2446. HANDLE* ptr = reinterpret_cast<HANDLE*>(::CoTaskMemAlloc(sizeof(HANDLE) * size));
  2447. for (auto& val : wil::make_range(ptr, size))
  2448. {
  2449. val = wil::unique_event(wil::EventOptions::ManualReset).release();
  2450. }
  2451. *events = ptr;
  2452. *count = size;
  2453. }
  2454. #endif
  2455. interface __declspec(uuid("EDCA4ADC-DF46-442A-A69D-FDFD8BC37B31")) IFakeObject : public IUnknown
  2456. {
  2457. STDMETHOD_(void, DoStuff)() = 0;
  2458. };
  2459. class ArrayTestObject : witest::AllocatedObject,
  2460. public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::ClassicCom>, IFakeObject>
  2461. {
  2462. public:
  2463. HRESULT RuntimeClassInitialize(UINT n) { m_number = n; return S_OK; };
  2464. STDMETHOD_(void, DoStuff)() {}
  2465. private:
  2466. UINT m_number{};
  2467. };
  2468. void GetUnknownArray(_Out_ size_t* count, _Outptr_result_buffer_(*count) IFakeObject*** objects)
  2469. {
  2470. const size_t size = 5;
  2471. auto ptr = reinterpret_cast<IFakeObject**>(::CoTaskMemAlloc(sizeof(IFakeObject*) * size));
  2472. REQUIRE(ptr);
  2473. for (UINT i = 0; i < size; ++i)
  2474. {
  2475. Microsoft::WRL::ComPtr<IFakeObject> obj;
  2476. REQUIRE_SUCCEEDED(Microsoft::WRL::MakeAndInitialize<ArrayTestObject>(&obj, i));
  2477. ptr[i] = obj.Detach();
  2478. }
  2479. *objects = ptr;
  2480. *count = size;
  2481. }
  2482. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  2483. TEST_CASE("WindowsInternalTests::TestUniqueArrayCases", "[resource]")
  2484. {
  2485. // wil::unique_cotaskmem_array_ptr tests
  2486. {
  2487. wil::unique_cotaskmem_array_ptr<DWORD> values;
  2488. GetDWORDArray(values.size_address(), &values);
  2489. }
  2490. {
  2491. wil::unique_cotaskmem_array_ptr<wil::unique_hstring> strings;
  2492. GetHSTRINGArray(strings.size_address<ULONG>(), &strings);
  2493. for (ULONG i = 0; i < strings.size(); ++i)
  2494. {
  2495. REQUIRE(WindowsGetStringLen(strings[i]) == wcslen(L"test"));
  2496. }
  2497. }
  2498. {
  2499. wil::unique_cotaskmem_array_ptr<POINT> points;
  2500. GetPOINTArray(points.size_address<UINT32>(), &points);
  2501. for (ULONG i = 0; i < points.size(); ++i)
  2502. {
  2503. REQUIRE((ULONG)points[i].x == i);
  2504. }
  2505. }
  2506. #ifdef WIL_ENABLE_EXCEPTIONS
  2507. {
  2508. wil::unique_cotaskmem_array_ptr<wil::unique_event> events;
  2509. GetHANDLEArray(events.size_address(), &events);
  2510. }
  2511. {
  2512. wil::unique_cotaskmem_array_ptr<wil::com_ptr<IFakeObject>> objects;
  2513. GetUnknownArray(objects.size_address(), &objects);
  2514. for (ULONG i = 0; i < objects.size(); ++i)
  2515. {
  2516. objects[i]->DoStuff();
  2517. }
  2518. }
  2519. #endif
  2520. {
  2521. wil::unique_cotaskmem_array_ptr<DWORD> values = nullptr;
  2522. REQUIRE(!values);
  2523. REQUIRE(values.size() == 0);
  2524. // move onto self
  2525. values = wistd::move(values);
  2526. REQUIRE(!values);
  2527. // fetch
  2528. GetDWORDArray(values.size_address(), &values);
  2529. REQUIRE(!!values);
  2530. REQUIRE(values.size() > 0);
  2531. REQUIRE(!values.empty());
  2532. // move onto self
  2533. values = wistd::move(values);
  2534. REQUIRE(!!values);
  2535. decltype(values) values2(wistd::move(values));
  2536. REQUIRE(!values);
  2537. REQUIRE(!!values2);
  2538. REQUIRE(values2.size() > 0);
  2539. values = wistd::move(values2);
  2540. REQUIRE(!!values);
  2541. REQUIRE(!values2);
  2542. values = nullptr;
  2543. REQUIRE(!values);
  2544. GetDWORDArray(values.size_address(), values.put());
  2545. REQUIRE(!!values);
  2546. values = nullptr;
  2547. REQUIRE(!values);
  2548. GetDWORDArray(values.size_address(), &values);
  2549. REQUIRE(!!values);
  2550. auto size = values.size();
  2551. auto ptr = values.release();
  2552. REQUIRE(!values);
  2553. REQUIRE(values.empty());
  2554. decltype(values) values3(ptr, size);
  2555. REQUIRE(!!values3);
  2556. REQUIRE(values3.size() == size);
  2557. values3.swap(values);
  2558. REQUIRE(!!values);
  2559. REQUIRE(!values.empty());
  2560. REQUIRE(!values3);
  2561. REQUIRE(values3.empty());
  2562. REQUIRE(!values.empty());
  2563. size_t count = 0;
  2564. for (auto it = values.begin(); it != values.end(); ++it)
  2565. {
  2566. ++count;
  2567. }
  2568. REQUIRE(count == values.size());
  2569. count = 0;
  2570. for (auto it = values.cbegin(); it != values.cend(); ++it)
  2571. {
  2572. ++count;
  2573. }
  2574. REQUIRE(count == values.size());
  2575. for (size_t index = 0; index < values.size(); index++)
  2576. {
  2577. auto& val = values[index];
  2578. REQUIRE(val == 0);
  2579. }
  2580. auto& front = values.front();
  2581. REQUIRE(front == 0);
  2582. auto& back = values.back();
  2583. REQUIRE(back == 0);
  2584. [](const wil::unique_cotaskmem_array_ptr<DWORD>& cvalues)
  2585. {
  2586. size_t count = 0;
  2587. for (auto it = cvalues.begin(); it != cvalues.end(); ++it)
  2588. {
  2589. ++count;
  2590. }
  2591. REQUIRE(count == cvalues.size());
  2592. for (size_t index = 0; index < cvalues.size(); index++)
  2593. {
  2594. auto& val = cvalues[index];
  2595. REQUIRE(val == 0);
  2596. }
  2597. auto& front = cvalues.front();
  2598. REQUIRE(front == 0);
  2599. auto& back = cvalues.back();
  2600. REQUIRE(back == 0);
  2601. REQUIRE(cvalues.data() != nullptr);
  2602. }(values);
  2603. auto data1 = values.data();
  2604. auto data2 = values.get();
  2605. REQUIRE((data1 && (data1 == data2)));
  2606. values.reset();
  2607. REQUIRE(!values);
  2608. REQUIRE(values.empty());
  2609. GetDWORDArray(values2.size_address(), &values2);
  2610. size = values2.size();
  2611. ptr = values2.release();
  2612. values.reset(ptr, size);
  2613. REQUIRE(!!values);
  2614. REQUIRE(!values.empty());
  2615. REQUIRE(values2.put() == values2.addressof());
  2616. REQUIRE(&values2 == values2.addressof());
  2617. }
  2618. }
  2619. #endif
  2620. #if !defined(__cplusplus_winrt) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
  2621. TEST_CASE("WindowsInternalTests::VerifyMakeAgileCallback", "[wrl]")
  2622. {
  2623. using namespace ABI::Windows::Foundation;
  2624. class CallbackClient
  2625. {
  2626. public:
  2627. HRESULT On(IMemoryBufferReference*, IInspectable*)
  2628. {
  2629. return S_OK;
  2630. }
  2631. };
  2632. CallbackClient callbackClient;
  2633. #ifdef WIL_ENABLE_EXCEPTIONS
  2634. auto cbAgile = wil::MakeAgileCallback<ITypedEventHandler<IMemoryBufferReference*, IInspectable*>>([](IMemoryBufferReference*, IInspectable*) -> HRESULT
  2635. {
  2636. return S_OK;
  2637. });
  2638. REQUIRE(wil::is_agile(cbAgile));
  2639. auto cbAgileWithMember = wil::MakeAgileCallback<ITypedEventHandler<IMemoryBufferReference*, IInspectable*>>(&callbackClient, &CallbackClient::On);
  2640. REQUIRE(wil::is_agile(cbAgileWithMember));
  2641. #endif
  2642. auto cbAgileNoThrow = wil::MakeAgileCallbackNoThrow<ITypedEventHandler<IMemoryBufferReference*, IInspectable*>>([](IMemoryBufferReference*, IInspectable*) -> HRESULT
  2643. {
  2644. return S_OK;
  2645. });
  2646. REQUIRE(wil::is_agile(cbAgileNoThrow));
  2647. auto cbAgileWithMemberNoThrow = wil::MakeAgileCallbackNoThrow<ITypedEventHandler<IMemoryBufferReference*, IInspectable*>>(&callbackClient, &CallbackClient::On);
  2648. REQUIRE(wil::is_agile(cbAgileWithMemberNoThrow));
  2649. }
  2650. #endif
  2651. TEST_CASE("WindowsInternalTests::Ranges", "[common]")
  2652. {
  2653. {
  2654. int things[10]{};
  2655. unsigned int count = 0;
  2656. for (auto& m : wil::make_range(things, ARRAYSIZE(things)))
  2657. {
  2658. ++count;
  2659. m = 1;
  2660. }
  2661. REQUIRE(ARRAYSIZE(things) == count);
  2662. REQUIRE(1 == things[1]);
  2663. }
  2664. {
  2665. int things[10]{};
  2666. unsigned int count = 0;
  2667. for (auto m : wil::make_range(things, ARRAYSIZE(things)))
  2668. {
  2669. ++count;
  2670. m = 1;
  2671. (void)m;
  2672. }
  2673. REQUIRE(ARRAYSIZE(things) == count);
  2674. REQUIRE(0 == things[0]);
  2675. }
  2676. {
  2677. int things[10]{};
  2678. unsigned int count = 0;
  2679. auto range = wil::make_range(things, ARRAYSIZE(things));
  2680. for (auto m : range)
  2681. {
  2682. (void)m;
  2683. ++count;
  2684. }
  2685. REQUIRE(ARRAYSIZE(things) == count);
  2686. }
  2687. {
  2688. int things[10]{};
  2689. unsigned int count = 0;
  2690. const auto range = wil::make_range(things, ARRAYSIZE(things));
  2691. for (auto m : range)
  2692. {
  2693. (void)m;
  2694. ++count;
  2695. }
  2696. REQUIRE(ARRAYSIZE(things) == count);
  2697. }
  2698. }
  2699. TEST_CASE("WindowsInternalTests::HStringTests", "[resource][unique_any]")
  2700. {
  2701. const wchar_t kittens[] = L"kittens";
  2702. {
  2703. wchar_t* bufferStorage = nullptr;
  2704. wil::unique_hstring_buffer theBuffer;
  2705. REQUIRE_SUCCEEDED(::WindowsPreallocateStringBuffer(ARRAYSIZE(kittens), &bufferStorage, &theBuffer));
  2706. REQUIRE_SUCCEEDED(StringCchCopyW(bufferStorage, ARRAYSIZE(kittens), kittens));
  2707. // Promote sets the promoted-to value but resets theBuffer
  2708. wil::unique_hstring promoted;
  2709. REQUIRE_SUCCEEDED(wil::make_hstring_from_buffer_nothrow(wistd::move(theBuffer), &promoted));
  2710. REQUIRE(static_cast<bool>(promoted));
  2711. REQUIRE_FALSE(static_cast<bool>(theBuffer));
  2712. }
  2713. {
  2714. wchar_t* bufferStorage = nullptr;
  2715. wil::unique_hstring_buffer theBuffer;
  2716. REQUIRE_SUCCEEDED(::WindowsPreallocateStringBuffer(ARRAYSIZE(kittens), &bufferStorage, &theBuffer));
  2717. REQUIRE_SUCCEEDED(StringCchCopyW(bufferStorage, ARRAYSIZE(kittens), kittens));
  2718. // Failure to promote retains the buffer state
  2719. REQUIRE_FAILED(wil::make_hstring_from_buffer_nothrow(wistd::move(theBuffer), nullptr));
  2720. REQUIRE(static_cast<bool>(theBuffer));
  2721. }
  2722. #ifdef WIL_ENABLE_EXCEPTIONS
  2723. {
  2724. wchar_t* bufferStorage = nullptr;
  2725. wil::unique_hstring_buffer theBuffer;
  2726. THROW_IF_FAILED(::WindowsPreallocateStringBuffer(ARRAYSIZE(kittens), &bufferStorage, &theBuffer));
  2727. THROW_IF_FAILED(StringCchCopyW(bufferStorage, ARRAYSIZE(kittens), kittens));
  2728. wil::unique_hstring promoted;
  2729. REQUIRE_NOTHROW(promoted = wil::make_hstring_from_buffer(wistd::move(theBuffer)));
  2730. REQUIRE(static_cast<bool>(promoted));
  2731. REQUIRE_FALSE(static_cast<bool>(theBuffer));
  2732. }
  2733. #endif
  2734. }
  2735. struct ThreadPoolWaitTestContext
  2736. {
  2737. volatile LONG Counter = 0;
  2738. wil::unique_event_nothrow Event;
  2739. };
  2740. static void __stdcall ThreadPoolWaitTestCallback(
  2741. _Inout_ PTP_CALLBACK_INSTANCE /*instance*/,
  2742. _Inout_opt_ void* context,
  2743. _Inout_ PTP_WAIT wait,
  2744. _In_ TP_WAIT_RESULT /*waitResult*/)
  2745. {
  2746. ThreadPoolWaitTestContext& myContext = *reinterpret_cast<ThreadPoolWaitTestContext*>(context);
  2747. SetThreadpoolWait(wait, myContext.Event.get(), nullptr);
  2748. ::InterlockedIncrement(&myContext.Counter);
  2749. }
  2750. template <typename WaitResourceT>
  2751. void ThreadPoolWaitTestHelper(bool requireExactCallbackCount)
  2752. {
  2753. ThreadPoolWaitTestContext myContext;
  2754. REQUIRE_SUCCEEDED(myContext.Event.create());
  2755. WaitResourceT wait;
  2756. wait.reset(CreateThreadpoolWait(ThreadPoolWaitTestCallback, &myContext, nullptr));
  2757. REQUIRE(wait);
  2758. SetThreadpoolWait(wait.get(), myContext.Event.get(), nullptr);
  2759. constexpr int loopCount = 5;
  2760. for (int currCallbackCount = 0; currCallbackCount != loopCount; ++currCallbackCount)
  2761. {
  2762. // Signal event.
  2763. myContext.Event.SetEvent();
  2764. // Wait until 'myContext.Counter' increments by 1.
  2765. for (int itr = 0; itr != 50 && currCallbackCount == myContext.Counter; ++itr)
  2766. {
  2767. Sleep(10);
  2768. }
  2769. // Ensure we didn't timeout
  2770. REQUIRE(currCallbackCount + 1 == myContext.Counter);
  2771. }
  2772. // Signal one last event.
  2773. myContext.Event.SetEvent();
  2774. // Close thread-pool wait.
  2775. wait.reset();
  2776. myContext.Event.reset();
  2777. // Verify counter.
  2778. if (requireExactCallbackCount)
  2779. {
  2780. REQUIRE(loopCount + 1 == myContext.Counter);
  2781. }
  2782. else
  2783. {
  2784. REQUIRE((loopCount + 1 == myContext.Counter || loopCount == myContext.Counter));
  2785. }
  2786. }
  2787. TEST_CASE("WindowsInternalTests::ThreadPoolWaitTest", "[resource][unique_threadpool_wait]")
  2788. {
  2789. ThreadPoolWaitTestHelper<wil::unique_threadpool_wait>(false);
  2790. ThreadPoolWaitTestHelper<wil::unique_threadpool_wait_nocancel>(true);
  2791. }
  2792. struct ThreadPoolWaitWorkContext
  2793. {
  2794. volatile LONG Counter = 0;
  2795. };
  2796. static void __stdcall ThreadPoolWaitWorkCallback(
  2797. _Inout_ PTP_CALLBACK_INSTANCE /*instance*/,
  2798. _Inout_opt_ void* context,
  2799. _Inout_ PTP_WORK /*work*/)
  2800. {
  2801. ThreadPoolWaitWorkContext& myContext = *reinterpret_cast<ThreadPoolWaitWorkContext*>(context);
  2802. ::InterlockedIncrement(&myContext.Counter);
  2803. }
  2804. template <typename WaitResourceT>
  2805. void ThreadPoolWaitWorkHelper(bool requireExactCallbackCount)
  2806. {
  2807. ThreadPoolWaitWorkContext myContext;
  2808. WaitResourceT work;
  2809. work.reset(CreateThreadpoolWork(ThreadPoolWaitWorkCallback, &myContext, nullptr));
  2810. REQUIRE(work);
  2811. constexpr int loopCount = 5;
  2812. for (int itr = 0; itr != loopCount; ++itr)
  2813. {
  2814. SubmitThreadpoolWork(work.get());
  2815. }
  2816. work.reset();
  2817. if (requireExactCallbackCount)
  2818. {
  2819. REQUIRE(loopCount == myContext.Counter);
  2820. }
  2821. else
  2822. {
  2823. REQUIRE(loopCount >= myContext.Counter);
  2824. }
  2825. }
  2826. TEST_CASE("WindowsInternalTests::ThreadPoolWorkTest", "[resource][unique_threadpool_work]")
  2827. {
  2828. ThreadPoolWaitWorkHelper<wil::unique_threadpool_work>(false);
  2829. ThreadPoolWaitWorkHelper<wil::unique_threadpool_work_nocancel>(true);
  2830. }
  2831. struct ThreadPoolTimerWorkContext
  2832. {
  2833. volatile LONG Counter = 0;
  2834. wil::unique_event_nothrow Event;
  2835. };
  2836. static void __stdcall ThreadPoolTimerWorkCallback(
  2837. _Inout_ PTP_CALLBACK_INSTANCE /*instance*/,
  2838. _Inout_opt_ void* context,
  2839. _Inout_ PTP_TIMER /*timer*/)
  2840. {
  2841. ThreadPoolTimerWorkContext& myContext = *reinterpret_cast<ThreadPoolTimerWorkContext*>(context);
  2842. myContext.Event.SetEvent();
  2843. ::InterlockedIncrement(&myContext.Counter);
  2844. }
  2845. template <typename TimerResourceT, typename DueTimeT, typename SetThreadpoolTimerT>
  2846. void ThreadPoolTimerWorkHelper(SetThreadpoolTimerT const &setThreadpoolTimerFn, bool requireExactCallbackCount)
  2847. {
  2848. ThreadPoolTimerWorkContext myContext;
  2849. REQUIRE_SUCCEEDED(myContext.Event.create());
  2850. TimerResourceT timer;
  2851. timer.reset(CreateThreadpoolTimer(ThreadPoolTimerWorkCallback, &myContext, nullptr));
  2852. REQUIRE(timer);
  2853. constexpr int loopCount = 5;
  2854. for (int currCallbackCount = 0; currCallbackCount != loopCount; ++currCallbackCount)
  2855. {
  2856. // Schedule timer
  2857. myContext.Event.ResetEvent();
  2858. const auto allowedWindow = 0;
  2859. LONGLONG dueTime = -5 * 10000I64; // 5ms
  2860. setThreadpoolTimerFn(timer.get(), reinterpret_cast<DueTimeT *>(&dueTime), 0, allowedWindow);
  2861. // Wait until 'myContext.Counter' increments by 1.
  2862. REQUIRE(myContext.Event.wait(500));
  2863. for (int itr = 0; itr != 50 && currCallbackCount == myContext.Counter; ++itr)
  2864. {
  2865. Sleep(10);
  2866. }
  2867. // Ensure we didn't timeout
  2868. REQUIRE(currCallbackCount + 1 == myContext.Counter);
  2869. }
  2870. // Schedule one last timer.
  2871. myContext.Event.ResetEvent();
  2872. const auto allowedWindow = 0;
  2873. LONGLONG dueTime = -5 * 10000I64; // 5ms
  2874. setThreadpoolTimerFn(timer.get(), reinterpret_cast<DueTimeT *>(&dueTime), 0, allowedWindow);
  2875. if (requireExactCallbackCount)
  2876. {
  2877. // Wait for the event to be set
  2878. REQUIRE(myContext.Event.wait(500));
  2879. }
  2880. // Close timer.
  2881. timer.reset();
  2882. myContext.Event.reset();
  2883. // Verify counter.
  2884. if (requireExactCallbackCount)
  2885. {
  2886. REQUIRE(loopCount + 1 == myContext.Counter);
  2887. }
  2888. else
  2889. {
  2890. REQUIRE((loopCount + 1 == myContext.Counter || loopCount == myContext.Counter));
  2891. }
  2892. }
  2893. TEST_CASE("WindowsInternalTests::ThreadPoolTimerTest", "[resource][unique_threadpool_timer]")
  2894. {
  2895. static_assert(sizeof(FILETIME) == sizeof(LONGLONG), "FILETIME and LONGLONG must be same size");
  2896. ThreadPoolTimerWorkHelper<wil::unique_threadpool_timer, FILETIME>(SetThreadpoolTimer, false);
  2897. ThreadPoolTimerWorkHelper<wil::unique_threadpool_timer_nocancel, FILETIME>(SetThreadpoolTimer, true);
  2898. }
  2899. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
  2900. static void __stdcall SlimEventTrollCallback(
  2901. _Inout_ PTP_CALLBACK_INSTANCE /*instance*/,
  2902. _Inout_opt_ void* context,
  2903. _Inout_ PTP_TIMER /*timer*/)
  2904. {
  2905. auto event = reinterpret_cast<wil::slim_event*>(context);
  2906. // Wake up the thread without setting the event.
  2907. // Note: This relies on the fact that the 'wil::slim_event' class only has a single member variable.
  2908. WakeByAddressAll(event);
  2909. }
  2910. static void __stdcall SlimEventFriendlyCallback(
  2911. _Inout_ PTP_CALLBACK_INSTANCE /*instance*/,
  2912. _Inout_opt_ void* context,
  2913. _Inout_ PTP_TIMER /*timer*/)
  2914. {
  2915. auto event = reinterpret_cast<wil::slim_event*>(context);
  2916. event->SetEvent();
  2917. }
  2918. TEST_CASE("WindowsInternalTests::SlimEventTests", "[resource][slim_event]")
  2919. {
  2920. {
  2921. wil::slim_event event;
  2922. // Verify simple timeouts work on an auto-reset event.
  2923. REQUIRE_FALSE(event.wait(/*timeout(ms)*/ 0));
  2924. REQUIRE_FALSE(event.wait(/*timeout(ms)*/ 10));
  2925. wil::unique_threadpool_timer trollTimer(CreateThreadpoolTimer(SlimEventTrollCallback, &event, nullptr));
  2926. REQUIRE(trollTimer);
  2927. FILETIME trollDueTime = wil::filetime::from_int64(0);
  2928. SetThreadpoolTimer(trollTimer.get(), &trollDueTime, /*period(ms)*/ 5, /*window(ms)*/ 0);
  2929. // Ensure we timeout in spite of being constantly woken up unnecessarily.
  2930. REQUIRE_FALSE(event.wait(/*timeout(ms)*/ 100));
  2931. wil::unique_threadpool_timer friendlyTimer(CreateThreadpoolTimer(SlimEventFriendlyCallback, &event, nullptr));
  2932. REQUIRE(friendlyTimer);
  2933. FILETIME friendlyDueTime = wil::filetime::from_int64(UINT64(-100 * wil::filetime_duration::one_millisecond)); // 100ms (relative to now)
  2934. SetThreadpoolTimer(friendlyTimer.get(), &friendlyDueTime, /*period(ms)*/ 0, /*window(ms)*/ 0);
  2935. // Now that the 'friendlyTimer' is queued, we should succeed.
  2936. REQUIRE(event.wait(INFINITE));
  2937. // Ensure event is auto-reset.
  2938. REQUIRE_FALSE(event.wait(/*timeout(ms)*/ 100));
  2939. }
  2940. {
  2941. wil::slim_event_manual_reset manualResetEvent;
  2942. // Verify simple timeouts work on a manual-reset event.
  2943. REQUIRE_FALSE(manualResetEvent.wait(/*timeout(ms)*/ 0));
  2944. REQUIRE_FALSE(manualResetEvent.wait(/*timeout(ms)*/ 10));
  2945. // Ensure multiple waits can occur on a manual-reset event.
  2946. manualResetEvent.SetEvent();
  2947. REQUIRE(manualResetEvent.wait());
  2948. REQUIRE(manualResetEvent.wait(/*timeout(ms)*/ 100));
  2949. REQUIRE(manualResetEvent.wait(INFINITE));
  2950. // Verify 'ResetEvent' works.
  2951. manualResetEvent.ResetEvent();
  2952. REQUIRE_FALSE(manualResetEvent.wait(/*timeout(ms)*/ 10));
  2953. }
  2954. }
  2955. #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
  2956. struct ConditionVariableCSCallbackContext
  2957. {
  2958. wil::condition_variable event;
  2959. wil::critical_section lock;
  2960. auto acquire() { return lock.lock(); }
  2961. };
  2962. struct ConditionVariableSRWCallbackContext
  2963. {
  2964. wil::condition_variable event;
  2965. wil::srwlock lock;
  2966. auto acquire() { return lock.lock_exclusive(); }
  2967. };
  2968. template <typename T>
  2969. static void __stdcall ConditionVariableCallback(
  2970. _Inout_ PTP_CALLBACK_INSTANCE /*Instance*/,
  2971. _In_ void* Context)
  2972. {
  2973. auto callbackContext = reinterpret_cast<T*>(Context);
  2974. // Acquire the lock to ensure we don't notify the condition variable before the other thread has
  2975. // gone to sleep.
  2976. auto gate = callbackContext->acquire();
  2977. // Signal the condition variable.
  2978. callbackContext->event.notify_all();
  2979. }
  2980. // A quick sanity check of the 'wil::condition_variable' type.
  2981. TEST_CASE("WindowsInternalTests::ConditionVariableTests", "[resource][condition_variable]")
  2982. {
  2983. SECTION("Test 'wil::condition_variable' with 'wil::critical_section'")
  2984. {
  2985. ConditionVariableCSCallbackContext callbackContext;
  2986. auto gate = callbackContext.lock.lock();
  2987. // Schedule the thread that will wake up this thread.
  2988. REQUIRE(TrySubmitThreadpoolCallback(ConditionVariableCallback<ConditionVariableCSCallbackContext>, &callbackContext, nullptr));
  2989. // Wait on the condition variable.
  2990. REQUIRE(callbackContext.event.wait_for(gate, /*timeout(ms)*/ 500));
  2991. }
  2992. SECTION("Test 'wil::condition_variable' with 'wil::srwlock'")
  2993. {
  2994. ConditionVariableSRWCallbackContext callbackContext;
  2995. // Test exclusive lock.
  2996. {
  2997. auto gate = callbackContext.lock.lock_exclusive();
  2998. // Schedule the thread that will wake up this thread.
  2999. REQUIRE(TrySubmitThreadpoolCallback(ConditionVariableCallback<ConditionVariableSRWCallbackContext>, &callbackContext, nullptr));
  3000. // Wait on the condition variable.
  3001. REQUIRE(callbackContext.event.wait_for(gate, /*timeout(ms)*/ 500));
  3002. }
  3003. // Test shared lock.
  3004. {
  3005. auto gate = callbackContext.lock.lock_shared();
  3006. // Schedule the thread that will wake up this thread.
  3007. REQUIRE(TrySubmitThreadpoolCallback(ConditionVariableCallback<ConditionVariableSRWCallbackContext>, &callbackContext, nullptr));
  3008. // Wait on the condition variable.
  3009. REQUIRE(callbackContext.event.wait_for(gate, /*timeout(ms)*/ 500));
  3010. }
  3011. }
  3012. }
  3013. TEST_CASE("WindowsInternalTests::ReturnWithExpectedTests", "[result_macros]")
  3014. {
  3015. wil::g_pfnResultLoggingCallback = ResultMacrosLoggingCallback;
  3016. // Succeeded
  3017. REQUIRE_RETURNS_EXPECTED(S_OK, [] { RETURN_IF_FAILED_WITH_EXPECTED(MDEC(hrOKRef()), E_UNEXPECTED); return S_OK; });
  3018. // Expected
  3019. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { RETURN_IF_FAILED_WITH_EXPECTED(E_FAIL, E_FAIL); return S_OK; });
  3020. REQUIRE_RETURNS_EXPECTED(E_UNEXPECTED, [] { RETURN_IF_FAILED_WITH_EXPECTED(E_UNEXPECTED, E_FAIL, E_UNEXPECTED, E_POINTER, E_INVALIDARG); return S_OK; });
  3021. // Unexpected
  3022. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { RETURN_IF_FAILED_WITH_EXPECTED(E_FAIL, E_UNEXPECTED); return S_OK; });
  3023. REQUIRE_RETURNS_EXPECTED(E_FAIL, [] { RETURN_IF_FAILED_WITH_EXPECTED(E_FAIL, E_UNEXPECTED, E_POINTER, E_INVALIDARG); return S_OK; });
  3024. }
  3025. TEST_CASE("WindowsInternalTests::LogWithExpectedTests", "[result_macros]")
  3026. {
  3027. wil::g_pfnResultLoggingCallback = ResultMacrosLoggingCallback;
  3028. // Succeeded
  3029. REQUIRE_LOG(S_OK, [] { REQUIRE(S_OK == LOG_IF_FAILED_WITH_EXPECTED(MDEC(hrOKRef()), E_FAIL, E_INVALIDARG)); });
  3030. // Expected
  3031. REQUIRE_LOG(S_OK, [] { REQUIRE(E_UNEXPECTED == LOG_IF_FAILED_WITH_EXPECTED(E_UNEXPECTED, E_UNEXPECTED, E_INVALIDARG)); });
  3032. REQUIRE_LOG(S_OK, [] { REQUIRE(E_UNEXPECTED == LOG_IF_FAILED_WITH_EXPECTED(E_UNEXPECTED, E_FAIL, E_UNEXPECTED, E_POINTER, E_INVALIDARG)); });
  3033. // Unexpected
  3034. REQUIRE_LOG(E_FAIL, [] { REQUIRE(E_FAIL == LOG_IF_FAILED_WITH_EXPECTED(E_FAIL, E_UNEXPECTED)); });
  3035. REQUIRE_LOG(E_FAIL, [] { REQUIRE(E_FAIL == LOG_IF_FAILED_WITH_EXPECTED(E_FAIL, E_UNEXPECTED, E_POINTER, E_INVALIDARG)); });
  3036. }
  3037. // Verifies that the shutdown-aware objects respect the alignment
  3038. // of the wrapped object.
  3039. template<template<typename> class Wrapper>
  3040. void VerifyAlignment()
  3041. {
  3042. // Some of the wrappers require a method called ProcessShutdown(), so we'll give it one.
  3043. struct alignment_sensitive_struct
  3044. {
  3045. // Use SLIST_HEADER as our poster child alignment-sensitive data type.
  3046. SLIST_HEADER value;
  3047. void ProcessShutdown() { }
  3048. };
  3049. static_assert(alignof(alignment_sensitive_struct) != alignof(char), "Need to choose a better alignment-sensitive type");
  3050. // Create a custom structure that tries to force misalignment.
  3051. struct attempted_misalignment
  3052. {
  3053. char c;
  3054. Wrapper<alignment_sensitive_struct> wrapper;
  3055. } possibly_misaligned{};
  3056. static_assert(alignof(attempted_misalignment) == alignof(alignment_sensitive_struct), "Wrapper type does not respect alignment");
  3057. // Verify that the wrapper type placed the inner object at proper alignment.
  3058. // Note: use std::addressof in case the alignment_sensitive_struct overrides the & operator.
  3059. REQUIRE(reinterpret_cast<uintptr_t>(std::addressof(possibly_misaligned.wrapper.get())) % alignof(alignment_sensitive_struct) == 0);
  3060. }
  3061. TEST_CASE("WindowsInternalTests::ShutdownAwareObjectAlignmentTests", "[result_macros]")
  3062. {
  3063. VerifyAlignment<wil::manually_managed_shutdown_aware_object>();
  3064. VerifyAlignment<wil::shutdown_aware_object>();
  3065. VerifyAlignment<wil::object_without_destructor_on_shutdown>();
  3066. }
  3067. #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
  3068. TEST_CASE("WindowsInternalTests::ModuleReference", "[wrl]")
  3069. {
  3070. REQUIRE(::Microsoft::WRL::GetModuleBase() == nullptr);
  3071. // Executables don't have a ModuleBase, so we need to create one.
  3072. struct FakeModuleBase : Microsoft::WRL::Details::ModuleBase
  3073. {
  3074. unsigned long count = 42;
  3075. STDMETHOD_(unsigned long, IncrementObjectCount)()
  3076. {
  3077. return InterlockedIncrement(&count);
  3078. }
  3079. STDMETHOD_(unsigned long, DecrementObjectCount)()
  3080. {
  3081. return InterlockedDecrement(&count);
  3082. }
  3083. STDMETHOD_(unsigned long, GetObjectCount)() const
  3084. {
  3085. return count;
  3086. }
  3087. // Dummy implementations of everything else (never called).
  3088. STDMETHOD_(const Microsoft::WRL::Details::CreatorMap**, GetFirstEntryPointer)() const { return nullptr; }
  3089. STDMETHOD_(const Microsoft::WRL::Details::CreatorMap**, GetMidEntryPointer)() const { return nullptr; }
  3090. STDMETHOD_(const Microsoft::WRL::Details::CreatorMap**, GetLastEntryPointer)() const { return nullptr; }
  3091. STDMETHOD_(SRWLOCK*, GetLock)() const { return nullptr; }
  3092. STDMETHOD(RegisterWinRTObject)(const wchar_t*, const wchar_t**, _Inout_ RO_REGISTRATION_COOKIE*, unsigned int) { return E_NOTIMPL; }
  3093. STDMETHOD(UnregisterWinRTObject)(const wchar_t*, _In_ RO_REGISTRATION_COOKIE) { return E_NOTIMPL; }
  3094. STDMETHOD(RegisterCOMObject)(const wchar_t*, _In_ IID*, _In_ IClassFactory**, _Inout_ DWORD*, unsigned int) { return E_NOTIMPL; }
  3095. STDMETHOD(UnregisterCOMObject)(const wchar_t*, _Inout_ DWORD*, unsigned int) { return E_NOTIMPL; }
  3096. };
  3097. FakeModuleBase fake;
  3098. auto peek_module_ref_count = []()
  3099. {
  3100. return ::Microsoft::WRL::GetModuleBase()->GetObjectCount();
  3101. };
  3102. auto initial = peek_module_ref_count();
  3103. // Basic test: Construct and destruct.
  3104. {
  3105. auto module_ref = wil::wrl_module_reference();
  3106. REQUIRE(peek_module_ref_count() == initial + 1);
  3107. }
  3108. REQUIRE(peek_module_ref_count() == initial);
  3109. // Fancy test: Copy object with embedded reference.
  3110. {
  3111. struct object_with_ref
  3112. {
  3113. wil::wrl_module_reference ref;
  3114. };
  3115. object_with_ref o1;
  3116. REQUIRE(peek_module_ref_count() == initial + 1);
  3117. auto o2 = o1;
  3118. REQUIRE(peek_module_ref_count() == initial + 2);
  3119. o1 = o2;
  3120. REQUIRE(peek_module_ref_count() == initial + 2);
  3121. o2 = std::move(o1);
  3122. REQUIRE(peek_module_ref_count() == initial + 2);
  3123. }
  3124. REQUIRE(peek_module_ref_count() == initial);
  3125. }
  3126. #endif
  3127. #if defined(WIL_ENABLE_EXCEPTIONS) && (defined(NTDDI_WIN10_CO) ? \
  3128. WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) : \
  3129. WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES))
  3130. TEST_CASE("WindowsInternalTests::VerifyModuleReferencesForThread", "[win32_helpers]")
  3131. {
  3132. bool success = true;
  3133. std::thread([&]
  3134. {
  3135. auto moduleRef = wil::get_module_reference_for_thread();
  3136. moduleRef.reset(); // results in exiting the thread
  3137. // should never get here
  3138. success = false;
  3139. FAIL();
  3140. }).join();
  3141. REQUIRE(success);
  3142. }
  3143. #endif
  3144. #pragma warning(pop)