Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.2 KiB

  1. #ifndef _SYNCHRO_H_
  2. #define _SYNCHRO_H_
  3. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4. //
  5. // SYNCHRO.H
  6. //
  7. // Header for DAV synchronization classes.
  8. //
  9. // Copyright 1986-1998 Microsoft Corporation, All Rights Reserved
  10. //
  11. #ifdef _DAVCDATA_
  12. #error "synchro.h: CInitGate can throw() -- not safe for DAVCDATA"
  13. #endif
  14. // Include common EXDAV-safe synchronization items
  15. #include <ex\stackbuf.h>
  16. #include <ex\synchro.h>
  17. #include <ex\autoptr.h>
  18. #include <stdio.h> // for swprintf()
  19. #include <except.h> // Exception throwing/handling
  20. // Security Descriptors ------------------------------------------------------
  21. //
  22. // ----------------------------------------------------------------------------
  23. //
  24. inline BOOL
  25. FCreateWorldSid (PSID * ppsidEveryone)
  26. {
  27. // Assert initialize output
  28. //
  29. Assert (ppsidEveryone);
  30. *ppsidEveryone = NULL;
  31. // An SID is built from an Identifier Authority and a set of Relative IDs
  32. // (RIDs). The Authority of interest to us SECURITY_NT_AUTHORITY.
  33. //
  34. SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
  35. // Each RID represents a sub-unit of the authority. The SID we want to
  36. // buils, Everyone, are in the "built in" domain.
  37. //
  38. // For examples of other useful SIDs consult the list in
  39. // \nt\public\sdk\inc\ntseapi.h.
  40. //
  41. return !AllocateAndInitializeSid (&siaWorld,
  42. 1, // 1 sub-authority
  43. SECURITY_WORLD_RID,
  44. 0,0,0,0,0,0,0,
  45. ppsidEveryone);
  46. }
  47. inline SECURITY_DESCRIPTOR *
  48. PsdCreateWorld ()
  49. {
  50. ACL *pacl = NULL;
  51. SECURITY_DESCRIPTOR * psd = NULL;
  52. SECURITY_DESCRIPTOR * psdRet = NULL;
  53. ULONG cbAcl = 0;
  54. PSID psidWorld = NULL;
  55. // Create the SID for the world (ie. everyone).
  56. //
  57. if (!FCreateWorldSid (&psidWorld))
  58. goto ret;
  59. // Calculate the size of and allocate a buffer for the DACL, we need
  60. // this value independently of the total alloc size for ACL init.
  61. //
  62. // "- sizeof (ULONG)" represents the SidStart field of the
  63. // ACCESS_ALLOWED_ACE. Since we're adding the entire length of the
  64. // SID, this field is counted twice.
  65. //
  66. cbAcl = sizeof(ACL)
  67. + (1 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (ULONG)))
  68. + GetLengthSid(psidWorld);
  69. // Allocate space for the acl
  70. //
  71. psd = static_cast<SECURITY_DESCRIPTOR *>
  72. (LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH + cbAcl));
  73. if (NULL == psd)
  74. goto ret;
  75. // Find the start of the ACL and initialize it.
  76. //
  77. pacl = reinterpret_cast<ACL *>
  78. (reinterpret_cast<BYTE *>(psd) + SECURITY_DESCRIPTOR_MIN_LENGTH);
  79. if (!InitializeAcl (pacl, cbAcl, ACL_REVISION))
  80. goto ret;
  81. if (!AddAccessAllowedAce (pacl,
  82. ACL_REVISION,
  83. SYNCHRONIZE | GENERIC_WRITE | GENERIC_READ,
  84. psidWorld))
  85. {
  86. // The security descriptor does not contain valid stuff, we need
  87. // to clean that up (via auto_heap_ptr, this is pretty easy).
  88. //
  89. goto ret;
  90. }
  91. // Set the security descriptor
  92. //
  93. if (!SetSecurityDescriptorDacl (psd,
  94. TRUE,
  95. pacl,
  96. FALSE))
  97. {
  98. // Again, the security descriptor does not contain valid stuff, we
  99. // need to clean that up (via auto_heap_ptr, this is pretty easy).
  100. //
  101. goto ret;
  102. }
  103. // Setup the return
  104. //
  105. psdRet = psd;
  106. psd = NULL;
  107. ret:
  108. if (psidWorld) FreeSid(psidWorld);
  109. if (psd) LocalFree (psd);
  110. return psdRet;
  111. }
  112. // ========================================================================
  113. //
  114. // CLASS CInitGate
  115. //
  116. // (The name of this class is purely historical)
  117. //
  118. // Encapsulates ONE-SHOT initialization of a globally NAMED object.
  119. //
  120. // Use to handle simultaneous on-demand initialization of named
  121. // per-process global objects. For on-demand initialization of
  122. // unnamed per-process global objects, use the templates in singlton.h.
  123. //
  124. class CInitGate
  125. {
  126. CEvent m_evt;
  127. BOOL m_fInit;
  128. // NOT IMPLEMENTED
  129. //
  130. CInitGate& operator=( const CInitGate& );
  131. CInitGate( const CInitGate& );
  132. public:
  133. CInitGate( LPCWSTR lpwszBaseName,
  134. LPCWSTR lpwszName ) :
  135. m_fInit(FALSE)
  136. {
  137. //
  138. // First, set up an empty security descriptor and attributes
  139. // so that the event can be created with no security
  140. // (i.e. accessible from any security context).
  141. //
  142. SECURITY_DESCRIPTOR * psdAllAccess = PsdCreateWorld();
  143. SECURITY_ATTRIBUTES saAllAccess;
  144. saAllAccess.nLength = sizeof(saAllAccess);
  145. saAllAccess.lpSecurityDescriptor = psdAllAccess;
  146. saAllAccess.bInheritHandle = FALSE;
  147. WCHAR lpwszEventName[MAX_PATH];
  148. if (MAX_PATH < (wcslen(lpwszBaseName) +
  149. wcslen(lpwszName) +
  150. 1))
  151. {
  152. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  153. throw CLastErrorException();
  154. }
  155. swprintf(lpwszEventName, L"%ls%ls", lpwszBaseName, lpwszName);
  156. if ( !m_evt.FCreate( &saAllAccess, // no security
  157. TRUE, // manual reset
  158. FALSE, // initially non-signalled
  159. lpwszEventName))
  160. {
  161. throw CLastErrorException();
  162. }
  163. if ( ERROR_ALREADY_EXISTS == GetLastError() )
  164. m_evt.Wait();
  165. else
  166. m_fInit = TRUE;
  167. LocalFree (psdAllAccess);
  168. }
  169. ~CInitGate()
  170. {
  171. if ( m_fInit )
  172. m_evt.Set();
  173. }
  174. BOOL FInit() const { return m_fInit; }
  175. };
  176. #endif // !defined(_SYNCHRO_H_)