Nui
corewrappers.h
Go to the documentation of this file.
1 //
2 // Copyright (C) Microsoft Corporation
3 // All rights reserved.
4 //
5 // Code in details namespace is for internal usage within the library code
6 //
7 #pragma once
8 
9 #include <windows.h>
10 #include <intsafe.h>
11 #include <winstring.h>
12 #include <roapi.h>
13 #ifdef BUILD_WINDOWS
14 # include <winrt.h>
15 #endif
16 
17 #include <wrl\def.h>
18 #include <wrl\internal.h>
19 
20 // Set packing
21 #pragma pack(push, 8)
22 
23 namespace Microsoft
24 {
25  namespace WRL
26  {
27 
28  namespace Details
29  {
30  // Need a type that isn't assignable from int (see other overloads of Initialize, that accept int as second
31  // arg) this is needed as part of EnableIf
32  struct Dummy
33  {};
34  }
35 
36  namespace Wrappers
37  {
38 
39  namespace HandleTraits
40  {
41  // Handle specializations for implemented RAII wrappers
43  {
44  typedef HANDLE Type;
45 
46  inline static bool Close(_In_ Type h) throw()
47  {
48  return ::CloseHandle(h) != FALSE;
49  }
50 
51  inline static Type GetInvalidValue() throw()
52  {
53  return nullptr;
54  }
55  };
56 
57  struct HANDLETraits
58  {
59  typedef HANDLE Type;
60 
61  inline static bool Close(_In_ Type h) throw()
62  {
63  return ::CloseHandle(h) != FALSE;
64  }
65 
66  inline static HANDLE GetInvalidValue() throw()
67  {
68  return INVALID_HANDLE_VALUE;
69  }
70  };
71 
73  {};
74 
76  {
77  typedef CRITICAL_SECTION* Type;
78 
79  inline static Type GetInvalidValue() throw()
80  {
81  return nullptr;
82  }
83 
84  _Releases_lock_(*cs) inline static void Unlock(_In_ Type cs) throw()
85  {
86  ::LeaveCriticalSection(cs);
87  }
88  };
89 
91  {
92  _Releases_lock_(h) inline static void Unlock(_In_ Type h) throw()
93  {
94  if (::ReleaseMutex(h) == FALSE)
95  {
96  // If we cannot release mutex it indicates
97  // bug in somebody code thus we raise an exception
98  ::Microsoft::WRL::Details::RaiseException(HRESULT_FROM_WIN32(GetLastError()));
99  }
100  }
101  };
102 
104  {
105  inline static void Unlock(_In_ Type h) throw()
106  {
107  if (::ReleaseSemaphore(h, 1, NULL) == FALSE)
108  {
109  // If we cannot release semaphore it indicates
110  // bug in somebody code thus we raise an exception
111  ::Microsoft::WRL::Details::RaiseException(HRESULT_FROM_WIN32(GetLastError()));
112  }
113  }
114  };
115 
117  {};
118 
120  {
121  typedef SRWLOCK* Type;
122 
123  inline static Type GetInvalidValue() throw()
124  {
125  return nullptr;
126  }
127 
128  _Releases_shared_lock_(*srwlock) inline static void Unlock(_In_ Type srwlock) throw()
129  {
130  ::ReleaseSRWLockShared(srwlock);
131  }
132  };
133 
135  {
136  typedef SRWLOCK* Type;
137 
138  inline static Type GetInvalidValue() throw()
139  {
140  return nullptr;
141  }
142 
143  _Releases_exclusive_lock_(*srwlock) inline static void Unlock(_In_ Type srwlock) throw()
144  {
145  ::ReleaseSRWLockExclusive(srwlock);
146  }
147  };
148 
149  } // namespace HandleTraits
150 
151  // Handle object implementation specialized with traits
152  template <typename HandleTraits>
153  class HandleT
154  {
155  public:
156  explicit HandleT(typename HandleTraits::Type h = HandleTraits::GetInvalidValue()) throw()
157  : handle_(h)
158  {}
159 
160  HandleT(_Inout_ HandleT&& h) throw()
161  : handle_(h.handle_)
162  {
163  h.handle_ = HandleTraits::GetInvalidValue();
164  }
165 
166  virtual ~HandleT() throw()
167  {
168  Close();
169  }
170 
171  HandleT& operator=(_Inout_ HandleT&& h) throw()
172  {
173  Close();
174  handle_ = h.handle_;
175  h.handle_ = HandleTraits::GetInvalidValue();
176  return *this;
177  }
178 
179  void Attach(typename HandleTraits::Type h) throw()
180  {
181  if (h != handle_)
182  {
183  Close();
184  handle_ = h;
185  }
186  }
187 
188  typename HandleTraits::Type Detach() throw()
189  {
190  typename HandleTraits::Type h = handle_;
191  handle_ = HandleTraits::GetInvalidValue();
192  return h;
193  }
194 
195  typename HandleTraits::Type Get() const throw()
196  {
197  return handle_;
198  }
199 
200  void Close() throw()
201  {
202  if (handle_ != HandleTraits::GetInvalidValue())
203  {
204  bool ret = InternalClose();
205  if (!ret)
206  {
207  // If we cannot close the handle it indicates
208  // bug in somebody code thus we raise an exception
209  ::Microsoft::WRL::Details::RaiseException(HRESULT_FROM_WIN32(GetLastError()));
210  }
211  handle_ = HandleTraits::GetInvalidValue();
212  }
213  }
214 
215  bool IsValid() const throw()
216  {
217  return handle_ != HandleTraits::GetInvalidValue();
218  }
219 
220  typename HandleTraits::Type* GetAddressOf() throw()
221  {
222  return &handle_;
223  }
224 
225  typename HandleTraits::Type* ReleaseAndGetAddressOf() throw()
226  {
227  Close();
228  return &handle_;
229  }
230 
231  typedef HandleTraits Traits;
232 
233  protected:
234  virtual bool InternalClose() throw()
235  {
236  return HandleTraits::Close(handle_);
237  }
238 
239  typename HandleTraits::Type handle_;
240 
241  private:
242  HandleT(const HandleT&);
243  HandleT& operator=(const HandleT&);
244  };
245 
246  // HandleT comparison operators
247  template <class T>
248  bool operator==(const HandleT<T>& rhs, const HandleT<T>& lhs) throw()
249  {
250  return rhs.Get() == lhs.Get();
251  }
252 
253  template <class T>
254  bool operator==(const typename HandleT<T>::Traits::Type& lhs, const HandleT<T>& rhs) throw()
255  {
256  return lhs == rhs.Get();
257  }
258 
259  template <class T>
260  bool operator==(const HandleT<T>& lhs, const typename HandleT<T>::Traits::Type& rhs) throw()
261  {
262  return lhs.Get() == rhs;
263  }
264 
265  template <class T>
266  bool operator!=(const HandleT<T>& lhs, const HandleT<T>& rhs) throw()
267  {
268  return lhs.Get() != rhs.Get();
269  }
270 
271  template <class T>
272  bool operator!=(const typename HandleT<T>::Traits::Type& lhs, const HandleT<T>& rhs) throw()
273  {
274  return lhs != rhs.Get();
275  }
276 
277  template <class T>
278  bool operator!=(const HandleT<T>& lhs, const typename HandleT<T>::Traits::Type& rhs) throw()
279  {
280  return lhs.Get() != rhs;
281  }
282 
283  template <class T>
284  bool operator<(const HandleT<T>& lhs, const HandleT<T>& rhs) throw()
285  {
286  return lhs.Get() < rhs.Get();
287  }
288 
290 
291  // Forward declarations
292  class CriticalSection;
293  class Mutex;
294  class Semaphore;
295  class SRWLock;
296 
297  namespace Details
298  {
299 
300 #ifdef _MSC_VER
301 # pragma warning(push)
302 // Disable unheld lock warning for RIAA objects
303 # pragma warning(disable : 26165)
304 #endif
305 
306  // Shared lock object for CriticalSection
308  {
309  public:
311  : sync_(other.sync_)
312  {
314  }
315 
316  _Releases_lock_(*sync_) ~SyncLockCriticalSection() throw()
317  {
318  InternalUnlock();
319  }
320 
321  _Releases_lock_(*sync_) void Unlock() throw()
322  {
324  InternalUnlock();
325  }
326 
327  bool IsLocked() const throw()
328  {
330  }
331 
333 
334  protected:
336  CRITICAL_SECTION* sync = HandleTraits::CriticalSectionTraits::GetInvalidValue()) throw()
337  : sync_(sync)
338  {}
339 
340  CRITICAL_SECTION* sync_;
341 
342  private:
343  // Disallow copy and assignment
346 
347  _Releases_lock_(*sync_) void InternalUnlock() throw()
348  {
349  if (IsLocked())
350  {
351  // Instances of this class should be used on the stack
352  // and should not be passed across threads.
353  // Unlock can fail if it is called from the wrong thread
354  // or with an Invalid Handle, both of which are bugs
355  // Traits::Unlock should raise an SEH in case it cannot
356  // release the lock
357 
360  }
361  }
362  };
363 
364  // Exclusive lock object for SRWLock
366  {
367  public:
368  SyncLockExclusive(_Inout_ SyncLockExclusive&& other) throw()
369  : sync_(other.sync_)
370  {
372  }
373 
374  _Releases_exclusive_lock_(*sync_) ~SyncLockExclusive() throw()
375  {
376  InternalUnlock();
377  }
378 
379  _Releases_exclusive_lock_(*sync_) void Unlock() throw()
380  {
382  InternalUnlock();
383  }
384 
385  bool IsLocked() const throw()
386  {
388  }
389 
390  friend class Wrappers::SRWLock;
391 
392  protected:
395  : sync_(sync)
396  {}
397 
398  SRWLOCK* sync_;
399 
400  private:
401  // Disallow copy and assignment
403  SyncLockExclusive& operator=(const SyncLockExclusive&);
404 
405  _Releases_exclusive_lock_(*sync_) void InternalUnlock() throw()
406  {
407  if (IsLocked())
408  {
411  ;
412  }
413  }
414  };
415 
416  // Shared lock object for SRWLock
418  {
419  public:
420  SyncLockShared(_Inout_ SyncLockShared&& other) throw()
421  : sync_(other.sync_)
422  {
424  }
425 
426  _Releases_shared_lock_(*sync_) ~SyncLockShared() throw()
427  {
428  InternalUnlock();
429  }
430 
431  _Releases_shared_lock_(*sync_) void Unlock() throw()
432  {
434  InternalUnlock();
435  }
436 
437  bool IsLocked() const throw()
438  {
440  }
441 
442  friend class Wrappers::SRWLock;
443 
444  protected:
445  explicit SyncLockShared(
446  SRWLOCK* sync = HandleTraits::SRWLockSharedTraits::GetInvalidValue()) throw()
447  : sync_(sync)
448  {}
449 
450  SRWLOCK* sync_;
451 
452  private:
453  // Disallow copy and assignment
455  SyncLockShared& operator=(const SyncLockShared&);
456 
457  _Releases_shared_lock_(*sync_) void InternalUnlock() throw()
458  {
459  if (IsLocked())
460  {
463  }
464  }
465  };
466 
467 #ifdef _MSC_VER
468 # pragma warning(pop)
469 
470 # pragma warning(push)
471 // Missing annotation _Releases_*
472 // Possibly releasing unheld lock
473 # pragma warning(disable : 26165 26167 26135)
474 #endif
475  // Lock object implemenatation customzed with traits
476  template <typename SyncTraits>
478  {
479  public:
480  SyncLockWithStatusT(_Inout_ SyncLockWithStatusT&& other) throw()
481  : sync_(other.sync_)
482  , status_(other.status_)
483  {
484  other.sync_ = SyncTraits::GetInvalidValue();
485  }
486 
488  {
489  InternalUnlock();
490  }
491 
492  void Unlock() throw()
493  {
495  InternalUnlock();
496  }
497 
498  bool IsLocked() const throw()
499  {
500  return sync_ != SyncTraits::GetInvalidValue() && (status_ == 0 || status_ == WAIT_ABANDONED);
501  }
502  // status value 0 indicates success
503  DWORD GetStatus() const throw()
504  {
505  return status_;
506  }
507 
508  friend class Wrappers::Mutex;
509  friend class Wrappers::Semaphore;
510 
511  protected:
512  explicit SyncLockWithStatusT(typename SyncTraits::Type sync, DWORD status) throw()
513  : status_(status)
514  , sync_(sync)
515  {}
516 
517  DWORD status_;
518  typename SyncTraits::Type sync_;
519 
520  private:
521  // Disallow copy and assignment
523  SyncLockWithStatusT& operator=(const SyncLockWithStatusT&);
524 
525  void InternalUnlock() throw()
526  {
527  if (IsLocked())
528  {
529  // Instances of this class should be used on the stack
530  // and should not be passed across threads.
531  // Unlock can fail if it is called from the wrong thread
532  // or with an Invalid Handle, both of which are bugs
533  // Traits::Unlock should raise an SEH in case it cannot
534  // release the lock
535 
536 // Cannot use _Analysis_assume_lock_held_(sync)
537 // because template instantiations have differing
538 // levels of indirection to the lock
539 #ifdef _MSC_VER
540 # pragma warning(suppress : 26110)
541 #endif
542  SyncTraits::Unlock(sync_);
543  sync_ = SyncTraits::GetInvalidValue();
544  }
545  }
546  };
547 
548 #ifdef _MSC_VER
549 # pragma warning(pop)
550 #endif
551 
552  } // namespace Details
553 
554  // Critical section implementation
556  {
557  public:
559 
560  explicit CriticalSection(ULONG spincount = 0) throw()
561  {
562  ::InitializeCriticalSectionEx(&cs_, spincount, 0);
563  }
564 
566  {
567  ::DeleteCriticalSection(&cs_);
568  }
569 
570  _Acquires_lock_(*return.sync_) _Post_same_lock_(*return.sync_, cs_) SyncLock Lock() throw()
571  {
572  return Lock(&cs_);
573  }
574 
575  _Acquires_lock_(*return.sync_) _Post_same_lock_(*return.sync_, *cs) static SyncLock
576  Lock(_In_ CRITICAL_SECTION* cs) throw()
577  {
578  ::EnterCriticalSection(cs);
579  return SyncLock(cs);
580  }
581 
582  _Acquires_lock_(*return.sync_) _Post_same_lock_(*return.sync_, cs_) SyncLock TryLock() throw()
583  {
584  return TryLock(&cs_);
585  }
586 
587  _Acquires_lock_(*return.sync_) _Post_same_lock_(*return.sync_, *cs) static SyncLock
588  TryLock(_In_ CRITICAL_SECTION* cs) throw()
589  {
590  bool acquired = !!::TryEnterCriticalSection(cs);
591  _Analysis_assume_lock_held_(*cs);
592  return SyncLock((acquired) ? cs : nullptr);
593  }
594 
595  bool IsValid() const throw()
596  {
597  return true;
598  }
599 
600  protected:
601  CRITICAL_SECTION cs_;
602 
603  private:
604  // Disallow copy and assignment
606  CriticalSection& operator=(const CriticalSection&);
607  };
608 
609  // Mutex handle implementation
610  class Mutex : public HandleT<HandleTraits::MutexTraits>
611  {
612  public:
614 
615  explicit Mutex(HANDLE h) throw()
616  : HandleT(h)
617  {}
618 
619  Mutex(_Inout_ Mutex&& h) throw()
621  {}
622 
623  Mutex& operator=(_Inout_ Mutex&& h) throw()
624  {
625  *static_cast<HandleT*>(this) = ::Microsoft::WRL::Details::Move(h);
626  return *this;
627  }
628 
629  SyncLock Lock(DWORD milliseconds = INFINITE) throw()
630  {
631  return Lock(Get(), milliseconds);
632  }
633 
634  static SyncLock Lock(HANDLE h, DWORD milliseconds = INFINITE) throw()
635  {
636  DWORD const status = ::WaitForSingleObjectEx(h, milliseconds, FALSE);
637  return SyncLock(h, status == WAIT_OBJECT_0 ? 0 : status);
638  }
639 
640  private:
641  void Close();
642  HANDLE Detach();
643  void Attach(HANDLE);
644  HANDLE* GetAddressOf();
645  HANDLE* ReleaseAndGetAddressOf();
646  };
647 
648  // Semaphore handle implementation
649  class Semaphore : public HandleT<HandleTraits::SemaphoreTraits>
650  {
651  public:
653 
654  explicit Semaphore(HANDLE h) throw()
655  : HandleT(h)
656  {}
657 
658  Semaphore(_Inout_ Semaphore&& h) throw()
660  {}
661 
662  Semaphore& operator=(_Inout_ Semaphore&& h) throw()
663  {
664  *static_cast<HandleT*>(this) = ::Microsoft::WRL::Details::Move(h);
665  return *this;
666  }
667 
668  SyncLock Lock(DWORD milliseconds = INFINITE) throw()
669  {
670  return Lock(Get(), milliseconds);
671  }
672 
673  static SyncLock Lock(HANDLE h, DWORD milliseconds = INFINITE) throw()
674  {
675  DWORD const status = ::WaitForSingleObjectEx(h, milliseconds, FALSE);
676  return SyncLock(h, status == WAIT_OBJECT_0 ? 0 : status);
677  }
678 
679  private:
680  void Close();
681  HANDLE Detach();
682  void Attach(HANDLE);
683  HANDLE* GetAddressOf();
684  HANDLE* ReleaseAndGetAddressOf();
685  };
686 
687  // Event handle implementation
688  class Event : public HandleT<HandleTraits::EventTraits>
689  {
690  public:
691  explicit Event(HANDLE h = HandleT::Traits::GetInvalidValue()) throw()
692  : HandleT(h)
693  {}
694 
695  Event(_Inout_ Event&& h) throw()
697  {}
698 
699  Event& operator=(_Inout_ Event&& h) throw()
700  {
701  *static_cast<HandleT*>(this) = ::Microsoft::WRL::Details::Move(h);
702  return *this;
703  }
704  };
705 
706  // SRW lock implementation
707  class SRWLock
708  {
709  public:
712 
713  SRWLock() throw()
714  {
715  ::InitializeSRWLock(&SRWLock_);
716  }
717 
718  ~SRWLock() throw()
719  {}
720 
721  _Acquires_exclusive_lock_(*return.sync_) _Post_same_lock_(*return.sync_, SRWLock_) SyncLockExclusive
722  LockExclusive() throw()
723  {
724  return LockExclusive(&SRWLock_);
725  }
726 
727  _Acquires_exclusive_lock_(*return.sync_) _Post_same_lock_(*return.sync_, *lock) static SyncLockExclusive
728  LockExclusive(_In_ SRWLOCK* lock) throw()
729  {
730  ::AcquireSRWLockExclusive(lock);
731  return SyncLockExclusive(lock);
732  }
733 
734  _Acquires_exclusive_lock_(*return.sync_) _Post_same_lock_(*return.sync_, SRWLock_) SyncLockExclusive
736  {
737  return TryLockExclusive(&SRWLock_);
738  }
739 
740  _Acquires_exclusive_lock_(*return.sync_) _Post_same_lock_(*return.sync_, *lock) static SyncLockExclusive
741  TryLockExclusive(_In_ SRWLOCK* lock) throw()
742  {
743  bool acquired = !!::TryAcquireSRWLockExclusive(lock);
744  _Analysis_assume_lock_held_(*lock);
745  return SyncLockExclusive((acquired) ? lock : nullptr);
746  }
747 
748  _Acquires_shared_lock_(*return.sync_) _Post_same_lock_(*return.sync_, SRWLock_) SyncLockShared
749  LockShared() throw()
750  {
751  return LockShared(&SRWLock_);
752  }
753 
754  _Acquires_shared_lock_(*return.sync_) _Post_same_lock_(*return.sync_, *lock) static SyncLockShared
755  LockShared(_In_ SRWLOCK* lock) throw()
756  {
757  ::AcquireSRWLockShared(lock);
758  return SyncLockShared(lock);
759  }
760 
761  _Acquires_shared_lock_(*return.sync_) _Post_same_lock_(*return.sync_, SRWLock_) SyncLockShared
762  TryLockShared() throw()
763  {
764  return TryLockShared(&SRWLock_);
765  }
766 
767  _Acquires_shared_lock_(*return.sync_) _Post_same_lock_(*return.sync_, *lock) static SyncLockShared
768  TryLockShared(_In_ SRWLOCK* lock) throw()
769  {
770  bool acquired = !!::TryAcquireSRWLockShared(lock);
771  _Analysis_assume_lock_held_(*lock);
772  return SyncLockShared((acquired) ? lock : nullptr);
773  }
774 
775  protected:
776  SRWLOCK SRWLock_;
777 
778  private:
779  // Disallow copy and assignment
780  SRWLock(const SRWLock&);
781  SRWLock& operator=(const SRWLock&);
782  };
783 
784  class HStringReference;
785 
786  class HString
787  {
788  public:
789  HString() throw()
790  : hstr_(nullptr)
791  {}
792 
793  HString(_Inout_ HString&& other) throw()
794  : hstr_(other.hstr_)
795  {
796  other.hstr_ = nullptr;
797  }
798 
799  ~HString() throw()
800  {
801  Release();
802  }
803 
804  HString& operator=(_Inout_ HString&& other) throw()
805  {
806  Release();
807  hstr_ = other.hstr_;
808  other.hstr_ = nullptr;
809  return *this;
810  }
811 
812  // Initialize this string from a source string. A copy is made in this call.
813  // The str parameter doesn't need to be null terminated, and it may have embedded NUL characters.
814  HRESULT Set(_In_reads_opt_(len) const wchar_t* str, unsigned int len) throw()
815  {
816  Release();
817  return ::WindowsCreateString(str, len, &hstr_);
818  }
819 
820  // Initialize the string from a const array of wchar_t. A copy is made in this call.
821  // The primary scenario here is the creation of a buffer from a string literal. Because the size is
822  // known, there is no need for length to be an explicit parameter.
823  template <size_t sizeDest>
824  HRESULT Set(const wchar_t (&str)[sizeDest]) throw()
825  {
826  static_assert(
827  static_cast<size_t>(static_cast<UINT32>(sizeDest - 1)) == sizeDest - 1,
828  "String length underflow or overflow");
829 
830  return Set(str, sizeDest - 1);
831  }
832 
833  // Initialize the string from a non-const array of wchar_t. A copy is made in this call.
834  // The input array must include a terminating NULL. This case differs from the
835  // one immediately above. This is intended to handle the case where the buffer size is known
836  // but the buffer may be oversized. This practice of using a buffer of known size that is
837  // guaranteed to be larger than necessary is a common optimization. This overload of initialize
838  // calls wcslen to get the length of the string and uses the size up to the first null as the length.
839  // If the caller desires to use a non-const buffer but is interested in getting support for
840  // embedded nulls, then the caller should use the overload that takes a length.
841  // Without this overload, the template above would match, and we actually want different behavior.
842  template <size_t sizeDest>
843  HRESULT Set(_In_z_ wchar_t (&strRef)[sizeDest]) throw()
844  {
845  const wchar_t* str = static_cast<const wchar_t*>(strRef);
846  unsigned int length;
847  HRESULT hr = SizeTToUInt32(::wcslen(str), &length);
848  if (SUCCEEDED(hr))
849  {
850  hr = Set(str, length);
851  }
852 
853  return hr;
854  }
855 
856  // Initialize this string from a source string. A copy is made in this call. The input string must have
857  // a terminating NULL. The EnableIf ensures that this overload is only for type convertible to const
858  // wchar_t*. Without the EnableIf, this overload would be chosen for type that is implicitly
859  // convertible to HSTRING, but we want the HSTRING overload to be chosen in such cases. A template
860  // version that matches a const wchar_t* is required because a simple non-templated overload with const
861  // wchar_t* argument would match before any templated version. And so the templated version above that
862  // infers length would never get called.
863  //
864  // WARNING: If Initialize is invoked with an extern wchar_t array of unknown size, this overload will be
865  // selected, but a compilation error will occur, reporting that the unknown-size array parameter could
866  // not be converted to 'const unsigned short (&)[1]' (or 'const wchar_t (&)[1]', depending on compiler
867  // switches). If such a compilation error is encountered, replace the extern declaration in a header
868  // file with an extern selectany initialization:
869  // extern const __declspec(selectany) WCHAR SomeString[] = L"SomeText";
870  // Alternatively, (but delivering less efficiency,) add an explicit static_cast to const wchar_t* at the
871  // call site.
872  template <typename T>
873  HRESULT
874  Set(__in_opt const T& strRef, // const-ref required in case caller has a type convertible to const
875  // wchar_t*, but not copy-able
876  typename ::Microsoft::WRL::Details::EnableIf<
877  __is_convertible_to(T, const wchar_t*),
879  {
880  HRESULT hr = E_POINTER;
881  const wchar_t* str = static_cast<PCWSTR>(strRef);
882  _Analysis_assume_nullterminated_(static_cast<void*>(const_cast<wchar_t*>(
883  str))); // we trust the caller's conversion gave us a null-terminated string as-advertised.
884 
885  if (str != nullptr)
886  {
887  unsigned int length;
888  hr = SizeTToUInt32(::wcslen(str), &length);
889  if (SUCCEEDED(hr))
890  {
891  hr = Set(str, length);
892  }
893  }
894  return hr;
895  }
896 
897  // Initialize this string from an HSTRING. A copy is made in this call.
898  HRESULT Set(const HSTRING& str) throw()
899  {
900  HRESULT hr = S_OK;
901 
902  // Guard against the case where this method is called with the argument this->hstr_ when this->hstr_
903  // is a valid HSTRING. If it's called with nullptr, allow ::WindowsDuplicateString() to return
904  // E_INVALIDARG no matter the value of this->hstr_
905  // if (static_cast<HSTRING>(str) == nullptr || static_cast<HSTRING>(str) != hstr_)
906  if (str == nullptr || str != hstr_)
907  {
908  Release();
909  hr = ::WindowsDuplicateString(str, &hstr_);
910  }
911 
912  return hr;
913  }
914 
915  void Attach(_In_opt_ HSTRING hstr) throw()
916  {
917  ::WindowsDeleteString(hstr_);
918  hstr_ = hstr;
919  }
920 
921  HSTRING Detach() throw()
922  {
923  HSTRING tmp = hstr_;
924  hstr_ = nullptr;
925  return tmp;
926  }
927 
928  HSTRING* GetAddressOf() throw()
929  {
930  Release();
931  return &hstr_;
932  }
933 
934  HSTRING Get() const throw()
935  {
936  return hstr_;
937  }
938 
939  void Release() throw()
940  {
941  ::WindowsDeleteString(hstr_);
942  hstr_ = nullptr;
943  }
944 
945  bool IsValid() const throw()
946  {
947  return hstr_ != nullptr;
948  }
949 
950  const wchar_t* GetRawBuffer(_Out_opt_ unsigned int* length) const
951  {
952  return ::WindowsGetStringRawBuffer(hstr_, length);
953  }
954 
955  HRESULT CopyTo(_Outptr_result_maybenull_ _Result_nullonfailure_ HSTRING* str) const throw()
956  {
957  return ::WindowsDuplicateString(hstr_, str);
958  }
959 
960  template <unsigned int sizeDest>
961  static HStringReference MakeReference(wchar_t const (&str)[sizeDest]) throw();
962 
963  template <unsigned int sizeDest>
964  static HStringReference MakeReference(wchar_t const (&str)[sizeDest], unsigned int len) throw();
965 
966  protected:
967  HSTRING hstr_;
968 
969  private:
970  HString(_In_ const HString&) throw();
971  HString& operator=(_In_ const HString&) throw();
972  };
973 
975  {
976  private:
977  void CreateReference(const wchar_t* str, unsigned int bufferLen, unsigned int len)
978  {
979  __WRL_ASSERT__(len < bufferLen);
980  if (len >= bufferLen)
981  {
982  len = bufferLen - 1;
983  }
984 
985  HRESULT hr = ::WindowsCreateStringReference(str, len, &header_, &hstr_);
986  // Failfast if developers try to create a reference to a non-NUL terminated string
987  if (FAILED(hr))
988  {
990  }
991  }
992 
994  : hstr_(nullptr)
995  {}
996 
997  public:
998  // Constructor which takes an existing string buffer and its length as the parameters.
999  // It fills an HSTRING_HEADER struct with the parameter.
1000  //
1001  // Warning: The caller must ensure the lifetime of the buffer outlives this
1002  // object as it does not make a copy of the wide string memory.
1003  HStringReference(const wchar_t* str, unsigned int len) throw()
1004  : hstr_(nullptr)
1005  {
1006  CreateReference(str, len + 1, len);
1007  }
1008 
1009  // Constructor which takes an existing literal string or const string buffer and infers its length.
1010  // It fills an HSTRING_HEADER struct with the parameter and length.
1011  template <unsigned int sizeDest>
1012  explicit HStringReference(wchar_t const (&str)[sizeDest]) throw()
1013  : hstr_(nullptr)
1014  {
1015  static_assert(
1016  static_cast<size_t>(static_cast<unsigned int>(sizeDest - 1)) == sizeDest - 1,
1017  "String length underflow or overflow");
1018 
1019  CreateReference(str, sizeDest, sizeDest - 1);
1020  }
1021 
1022  // Constructor which takes an non-const string buffer, and uses wcslen() to determine the string's
1023  // length. It fills an HSTRING_HEADER struct with the parameter and length. For additional information,
1024  // see the comments for String.Initialize above that takes the same template parameters
1025  template <size_t sizeDest>
1026  explicit HStringReference(_In_z_ wchar_t (&strRef)[sizeDest]) throw()
1027  {
1028  const wchar_t* str = static_cast<const wchar_t*>(strRef);
1029 
1030  unsigned int length;
1031  HRESULT hr = SizeTToUInt32(::wcslen(str), &length);
1032  if (FAILED(hr))
1033  {
1035  }
1036 
1037  CreateReference(str, length + 1, length);
1038  }
1039 
1040  // Constructor which takes an existing zero-terminated string buffer.
1041  // It fills an HSTRING_HEADER struct with the parameter and length.
1042  template <typename T>
1044  _In_ const T& strRef, // const-ref required in case caller has a type convertible to const wchar_t*,
1045  // but not copy-able
1046  typename ::Microsoft::WRL::Details::EnableIf<
1047  __is_convertible_to(T, const wchar_t*),
1049  : hstr_(nullptr)
1050  {
1051  const wchar_t* str = static_cast<const wchar_t*>(strRef);
1052  _Analysis_assume_nullterminated_(static_cast<void*>(const_cast<wchar_t*>(str)));
1053  _Analysis_assume_(strlen(reinterpret_cast<const char*>(str)) >= sizeof(wchar_t));
1054 
1055  unsigned int length;
1056  HRESULT hr = SizeTToUInt32(::wcslen(str), &length);
1057  if (FAILED(hr))
1058  {
1060  }
1061 
1062  CreateReference(str, length + 1, length);
1063  }
1064 
1065  HStringReference(_In_ const HStringReference& other) throw()
1066  : hstr_(nullptr)
1067  {
1068  unsigned int length = 0;
1069  const wchar_t* value = other.GetRawBuffer(&length);
1070  CreateReference(value, length + 1, length);
1071  }
1072 
1074  {
1075  hstr_ = nullptr;
1076  }
1077 
1078  HStringReference& operator=(_In_ const HStringReference& other) throw()
1079  {
1080  unsigned int length = 0;
1081  const wchar_t* value = other.GetRawBuffer(&length);
1082  CreateReference(value, length + 1, length);
1083 
1084  return *this;
1085  }
1086 
1087  HSTRING Get() const throw()
1088  {
1089  return hstr_;
1090  }
1091 
1092  const wchar_t* GetRawBuffer(_Out_opt_ unsigned int* length) const
1093  {
1094  return ::WindowsGetStringRawBuffer(hstr_, length);
1095  }
1096 
1097  HRESULT CopyTo(_Outptr_result_maybenull_ _Result_nullonfailure_ HSTRING* str) const throw()
1098  {
1099  return ::WindowsDuplicateString(hstr_, str);
1100  }
1101 
1102  friend class HString;
1103 
1104  protected:
1105  HSTRING_HEADER header_;
1106  HSTRING hstr_;
1107  };
1108 
1109  template <unsigned int sizeDest>
1110  inline HStringReference HString::MakeReference(wchar_t const (&str)[sizeDest]) throw()
1111  {
1112  static_assert(
1113  static_cast<size_t>(static_cast<unsigned int>(sizeDest - 1)) == sizeDest - 1,
1114  "String length underflow or overflow");
1115 
1116  HStringReference hstringRef;
1117  hstringRef.CreateReference(str, sizeDest, sizeDest - 1);
1118  return hstringRef;
1119  }
1120 
1121  template <unsigned int sizeDest>
1122  inline HStringReference HString::MakeReference(wchar_t const (&str)[sizeDest], unsigned int len) throw()
1123  {
1124  HStringReference hstringRef;
1125  hstringRef.CreateReference(str, sizeDest, len);
1126  return hstringRef;
1127  }
1128 
1129  namespace Details
1130  {
1131  inline INT32 CompareStringOrdinal(HSTRING lhs, HSTRING rhs)
1132  {
1133  INT32 result = 0;
1134  HRESULT hr = S_OK;
1135  // Ignore the HRESULT from the following call
1136  hr = ::WindowsCompareStringOrdinal(lhs, rhs, &result);
1137  if (SUCCEEDED(hr))
1138  {
1139  return result;
1140  }
1141  else
1142  {
1144  return 0;
1145  }
1146  }
1147 
1148  } // namespace Details
1149 
1150  // Specialization for HString
1151  inline bool operator==(const HString& lhs, const HString& rhs) throw()
1152  {
1153  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) == 0;
1154  }
1155 
1156  inline bool operator==(const HString& lhs, const HStringReference& rhs) throw()
1157  {
1158  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) == 0;
1159  }
1160 
1161  inline bool operator==(const HStringReference& lhs, const HString& rhs) throw()
1162  {
1163  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) == 0;
1164  }
1165 
1166  inline bool operator==(const HSTRING& lhs, const HString& rhs) throw()
1167  {
1168  return Details::CompareStringOrdinal(lhs, rhs.Get()) == 0;
1169  }
1170 
1171  inline bool operator==(const HString& lhs, const HSTRING& rhs) throw()
1172  {
1173  return Details::CompareStringOrdinal(lhs.Get(), rhs) == 0;
1174  }
1175 
1176  inline bool operator!=(const HString& lhs, const HString& rhs) throw()
1177  {
1178  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) != 0;
1179  }
1180 
1181  inline bool operator!=(const HStringReference& lhs, const HString& rhs) throw()
1182  {
1183  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) != 0;
1184  }
1185 
1186  inline bool operator!=(const HString& lhs, const HStringReference& rhs) throw()
1187  {
1188  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) != 0;
1189  }
1190 
1191  inline bool operator!=(const HSTRING& lhs, const HString& rhs) throw()
1192  {
1193  return Details::CompareStringOrdinal(lhs, rhs.Get()) != 0;
1194  }
1195 
1196  inline bool operator!=(const HString& lhs, const HSTRING& rhs) throw()
1197  {
1198  return Details::CompareStringOrdinal(lhs.Get(), rhs) != 0;
1199  }
1200 
1201  inline bool operator<(const HString& lhs, const HString& rhs) throw()
1202  {
1203  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) == 1;
1204  }
1205 
1206  // Specialization for HStringReference
1207  inline bool operator==(const HStringReference& rhs, const HStringReference& lhs) throw()
1208  {
1209  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) == 0;
1210  }
1211 
1212  inline bool operator==(const HSTRING& lhs, const HStringReference& rhs) throw()
1213  {
1214  return Details::CompareStringOrdinal(lhs, rhs.Get()) == 0;
1215  }
1216 
1217  inline bool operator==(const HStringReference& lhs, const HSTRING& rhs) throw()
1218  {
1219  return Details::CompareStringOrdinal(lhs.Get(), rhs) == 0;
1220  }
1221 
1222  inline bool operator!=(const HStringReference& lhs, const HStringReference& rhs) throw()
1223  {
1224  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) != 0;
1225  }
1226 
1227  inline bool operator!=(const HSTRING& lhs, const HStringReference& rhs) throw()
1228  {
1229  return Details::CompareStringOrdinal(lhs, rhs.Get()) != 0;
1230  }
1231 
1232  inline bool operator!=(const HStringReference& lhs, const HSTRING& rhs) throw()
1233  {
1234  return Details::CompareStringOrdinal(lhs.Get(), rhs) != 0;
1235  }
1236 
1237  inline bool operator<(const HStringReference& lhs, const HStringReference& rhs) throw()
1238  {
1239  return Details::CompareStringOrdinal(lhs.Get(), rhs.Get()) == 1;
1240  }
1241 
1243  {
1244  HRESULT _hr;
1245 
1246  public:
1247  RoInitializeWrapper(RO_INIT_TYPE flags)
1248  {
1249  _hr = ::Windows::Foundation::Initialize(flags);
1250  }
1252  {
1253  if (SUCCEEDED(_hr))
1254  {
1255  ::Windows::Foundation::Uninitialize();
1256  }
1257  }
1258  operator HRESULT()
1259  {
1260  return _hr;
1261  }
1262  };
1263 
1264  }
1265  }
1266 } // namespace ::Microsoft::WRL::Wrappers
1267 
1268 // Restore packing
1269 #pragma pack(pop)
Definition: corewrappers.h:556
_Acquires_lock_ return _Post_same_lock_ return SyncLock TryLock()
Definition: corewrappers.h:582
_Acquires_lock_ return _Post_same_lock_ static return SyncLock TryLock(_In_ CRITICAL_SECTION *cs)
Definition: corewrappers.h:588
Details::SyncLockCriticalSection SyncLock
Definition: corewrappers.h:558
~CriticalSection()
Definition: corewrappers.h:565
_Acquires_lock_ return _Post_same_lock_ static return SyncLock Lock(_In_ CRITICAL_SECTION *cs)
Definition: corewrappers.h:576
CRITICAL_SECTION cs_
Definition: corewrappers.h:601
_Acquires_lock_ return _Post_same_lock_ return SyncLock Lock()
Definition: corewrappers.h:570
bool IsValid() const
Definition: corewrappers.h:595
CriticalSection(ULONG spincount=0)
Definition: corewrappers.h:560
_Releases_lock_ sync_ ~SyncLockCriticalSection()
Definition: corewrappers.h:316
SyncLockCriticalSection(_Inout_ SyncLockCriticalSection &&other)
Definition: corewrappers.h:310
CRITICAL_SECTION * sync_
Definition: corewrappers.h:340
bool IsLocked() const
Definition: corewrappers.h:327
SyncLockCriticalSection(CRITICAL_SECTION *sync=HandleTraits::CriticalSectionTraits::GetInvalidValue())
Definition: corewrappers.h:335
_Releases_lock_ sync_ void Unlock()
Definition: corewrappers.h:321
SyncLockExclusive(_Inout_ SyncLockExclusive &&other)
Definition: corewrappers.h:368
_Releases_exclusive_lock_ sync_ ~SyncLockExclusive()
Definition: corewrappers.h:374
bool IsLocked() const
Definition: corewrappers.h:385
SyncLockExclusive(SRWLOCK *sync=HandleTraits::SRWLockExclusiveTraits::GetInvalidValue())
Definition: corewrappers.h:393
SRWLOCK * sync_
Definition: corewrappers.h:398
_Releases_exclusive_lock_ sync_ void Unlock()
Definition: corewrappers.h:379
_Releases_shared_lock_ sync_ void Unlock()
Definition: corewrappers.h:431
SyncLockShared(_Inout_ SyncLockShared &&other)
Definition: corewrappers.h:420
SyncLockShared(SRWLOCK *sync=HandleTraits::SRWLockSharedTraits::GetInvalidValue())
Definition: corewrappers.h:445
bool IsLocked() const
Definition: corewrappers.h:437
_Releases_shared_lock_ sync_ ~SyncLockShared()
Definition: corewrappers.h:426
SRWLOCK * sync_
Definition: corewrappers.h:450
SyncTraits::Type sync_
Definition: corewrappers.h:518
void Unlock()
Definition: corewrappers.h:492
SyncLockWithStatusT(typename SyncTraits::Type sync, DWORD status)
Definition: corewrappers.h:512
DWORD status_
Definition: corewrappers.h:517
DWORD GetStatus() const
Definition: corewrappers.h:503
~SyncLockWithStatusT()
Definition: corewrappers.h:487
SyncLockWithStatusT(_Inout_ SyncLockWithStatusT &&other)
Definition: corewrappers.h:480
bool IsLocked() const
Definition: corewrappers.h:498
Definition: corewrappers.h:689
Event & operator=(_Inout_ Event &&h)
Definition: corewrappers.h:699
Event(HANDLE h=HandleT::Traits::GetInvalidValue())
Definition: corewrappers.h:691
Event(_Inout_ Event &&h)
Definition: corewrappers.h:695
Definition: corewrappers.h:975
HStringReference(_In_z_ wchar_t(&strRef)[sizeDest])
Definition: corewrappers.h:1026
HStringReference(_In_ const HStringReference &other)
Definition: corewrappers.h:1065
HStringReference & operator=(_In_ const HStringReference &other)
Definition: corewrappers.h:1078
HStringReference(const wchar_t *str, unsigned int len)
Definition: corewrappers.h:1003
~HStringReference()
Definition: corewrappers.h:1073
HSTRING hstr_
Definition: corewrappers.h:1106
HRESULT CopyTo(_Outptr_result_maybenull_ _Result_nullonfailure_ HSTRING *str) const
Definition: corewrappers.h:1097
HStringReference(_In_ const T &strRef, typename ::Microsoft::WRL::Details::EnableIf< __is_convertible_to(T, const wchar_t *), ::Microsoft::WRL::Details::Dummy >::type=::Microsoft::WRL::Details::Dummy())
Definition: corewrappers.h:1043
const wchar_t * GetRawBuffer(_Out_opt_ unsigned int *length) const
Definition: corewrappers.h:1092
HSTRING_HEADER header_
Definition: corewrappers.h:1105
HStringReference(wchar_t const (&str)[sizeDest])
Definition: corewrappers.h:1012
HSTRING Get() const
Definition: corewrappers.h:1087
Definition: corewrappers.h:787
bool IsValid() const
Definition: corewrappers.h:945
HSTRING Detach()
Definition: corewrappers.h:921
void Attach(_In_opt_ HSTRING hstr)
Definition: corewrappers.h:915
HSTRING hstr_
Definition: corewrappers.h:967
HRESULT CopyTo(_Outptr_result_maybenull_ _Result_nullonfailure_ HSTRING *str) const
Definition: corewrappers.h:955
static HStringReference MakeReference(wchar_t const (&str)[sizeDest])
Definition: corewrappers.h:1110
~HString()
Definition: corewrappers.h:799
void Release()
Definition: corewrappers.h:939
HString()
Definition: corewrappers.h:789
HRESULT Set(_In_reads_opt_(len) const wchar_t *str, unsigned int len)
Definition: corewrappers.h:814
HString(_Inout_ HString &&other)
Definition: corewrappers.h:793
const wchar_t * GetRawBuffer(_Out_opt_ unsigned int *length) const
Definition: corewrappers.h:950
HString & operator=(_Inout_ HString &&other)
Definition: corewrappers.h:804
HRESULT Set(const wchar_t(&str)[sizeDest])
Definition: corewrappers.h:824
HRESULT Set(__in_opt const T &strRef, typename ::Microsoft::WRL::Details::EnableIf< __is_convertible_to(T, const wchar_t *), ::Microsoft::WRL::Details::Dummy >::type=::Microsoft::WRL::Details::Dummy())
Definition: corewrappers.h:874
HSTRING * GetAddressOf()
Definition: corewrappers.h:928
HSTRING Get() const
Definition: corewrappers.h:934
HRESULT Set(_In_z_ wchar_t(&strRef)[sizeDest])
Definition: corewrappers.h:843
HRESULT Set(const HSTRING &str)
Definition: corewrappers.h:898
Definition: corewrappers.h:154
virtual bool InternalClose()
Definition: corewrappers.h:234
HandleTraits::Type * GetAddressOf()
Definition: corewrappers.h:220
HandleT(typename HandleTraits::Type h=HandleTraits::GetInvalidValue())
Definition: corewrappers.h:156
HandleTraits::Type * ReleaseAndGetAddressOf()
Definition: corewrappers.h:225
HandleTraits::Type Detach()
Definition: corewrappers.h:188
virtual ~HandleT()
Definition: corewrappers.h:166
HandleT & operator=(_Inout_ HandleT &&h)
Definition: corewrappers.h:171
HandleT(_Inout_ HandleT &&h)
Definition: corewrappers.h:160
HandleTraits Traits
Definition: corewrappers.h:231
void Close()
Definition: corewrappers.h:200
HandleTraits::Type handle_
Definition: corewrappers.h:239
void Attach(typename HandleTraits::Type h)
Definition: corewrappers.h:179
bool IsValid() const
Definition: corewrappers.h:215
HandleTraits::Type Get() const
Definition: corewrappers.h:195
Definition: corewrappers.h:611
Mutex(_Inout_ Mutex &&h)
Definition: corewrappers.h:619
SyncLock Lock(DWORD milliseconds=INFINITE)
Definition: corewrappers.h:629
Mutex & operator=(_Inout_ Mutex &&h)
Definition: corewrappers.h:623
static SyncLock Lock(HANDLE h, DWORD milliseconds=INFINITE)
Definition: corewrappers.h:634
Mutex(HANDLE h)
Definition: corewrappers.h:615
Details::SyncLockWithStatusT< HandleTraits::MutexTraits > SyncLock
Definition: corewrappers.h:613
Definition: corewrappers.h:1243
~RoInitializeWrapper()
Definition: corewrappers.h:1251
RoInitializeWrapper(RO_INIT_TYPE flags)
Definition: corewrappers.h:1247
Definition: corewrappers.h:708
SRWLOCK SRWLock_
Definition: corewrappers.h:776
_Acquires_shared_lock_ return _Post_same_lock_ static return SyncLockShared LockShared(_In_ SRWLOCK *lock)
Definition: corewrappers.h:755
Details::SyncLockExclusive SyncLockExclusive
Definition: corewrappers.h:710
Details::SyncLockShared SyncLockShared
Definition: corewrappers.h:711
SRWLock()
Definition: corewrappers.h:713
~SRWLock()
Definition: corewrappers.h:718
_Acquires_exclusive_lock_ return _Post_same_lock_ return SyncLockExclusive LockExclusive()
Definition: corewrappers.h:722
_Acquires_shared_lock_ return _Post_same_lock_ return SyncLockShared TryLockShared()
Definition: corewrappers.h:762
_Acquires_exclusive_lock_ return _Post_same_lock_ static return SyncLockExclusive LockExclusive(_In_ SRWLOCK *lock)
Definition: corewrappers.h:728
_Acquires_exclusive_lock_ return _Post_same_lock_ static return SyncLockExclusive TryLockExclusive(_In_ SRWLOCK *lock)
Definition: corewrappers.h:741
_Acquires_shared_lock_ return _Post_same_lock_ return SyncLockShared LockShared()
Definition: corewrappers.h:749
_Acquires_exclusive_lock_ return _Post_same_lock_ return SyncLockExclusive TryLockExclusive()
Definition: corewrappers.h:735
_Acquires_shared_lock_ return _Post_same_lock_ static return SyncLockShared TryLockShared(_In_ SRWLOCK *lock)
Definition: corewrappers.h:768
Definition: corewrappers.h:650
Semaphore & operator=(_Inout_ Semaphore &&h)
Definition: corewrappers.h:662
Semaphore(HANDLE h)
Definition: corewrappers.h:654
Semaphore(_Inout_ Semaphore &&h)
Definition: corewrappers.h:658
SyncLock Lock(DWORD milliseconds=INFINITE)
Definition: corewrappers.h:668
static SyncLock Lock(HANDLE h, DWORD milliseconds=INFINITE)
Definition: corewrappers.h:673
Details::SyncLockWithStatusT< HandleTraits::SemaphoreTraits > SyncLock
Definition: corewrappers.h:652
#define __WRL_ASSERT__(cond)
Definition: internal.h:13
void RaiseException(HRESULT hr, DWORD dwExceptionFlags=EXCEPTION_NONCONTINUABLE)
Definition: internal.h:49
RemoveReference< T >::Type && Move(_Inout_ T &&arg)
Definition: internal.h:95
INT32 CompareStringOrdinal(HSTRING lhs, HSTRING rhs)
Definition: corewrappers.h:1131
bool operator==(const HandleT< T > &rhs, const HandleT< T > &lhs)
Definition: corewrappers.h:248
bool operator<(const HandleT< T > &lhs, const HandleT< T > &rhs)
Definition: corewrappers.h:284
HandleT< HandleTraits::FileHandleTraits > FileHandle
Definition: corewrappers.h:289
bool operator!=(const HandleT< T > &lhs, const HandleT< T > &rhs)
Definition: corewrappers.h:266
This file has no copyright assigned and is placed in the Public Domain.
Definition: client.h:26
Definition: corewrappers.h:33
CRITICAL_SECTION * Type
Definition: corewrappers.h:77
_Releases_lock_ static cs void Unlock(_In_ Type cs)
Definition: corewrappers.h:84
static Type GetInvalidValue()
Definition: corewrappers.h:79
static Type GetInvalidValue()
Definition: corewrappers.h:51
static bool Close(_In_ Type h)
Definition: corewrappers.h:46
static bool Close(_In_ Type h)
Definition: corewrappers.h:61
static HANDLE GetInvalidValue()
Definition: corewrappers.h:66
HANDLE Type
Definition: corewrappers.h:59
_Releases_lock_(h) inline static void Unlock(_In_ Type h)
Definition: corewrappers.h:92
_Releases_exclusive_lock_ static srwlock void Unlock(_In_ Type srwlock)
Definition: corewrappers.h:143
static Type GetInvalidValue()
Definition: corewrappers.h:138
static Type GetInvalidValue()
Definition: corewrappers.h:123
SRWLOCK * Type
Definition: corewrappers.h:121
_Releases_shared_lock_ static srwlock void Unlock(_In_ Type srwlock)
Definition: corewrappers.h:128
static void Unlock(_In_ Type h)
Definition: corewrappers.h:105