Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

420 lines
11 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. rtutil.cpp
  5. Abstract:
  6. Contains various utility functions.
  7. Author:
  8. Boaz Feldbaum (BoazF) Mar 5, 1996
  9. Revision History:
  10. Erez Haba (erezh) 17-Jan-1997
  11. --*/
  12. #include "stdh.h"
  13. #include "acrt.h"
  14. #include <mqdbmgr.h>
  15. #include <ad.h>
  16. #include <_secutil.h>
  17. #include <mqsec.h>
  18. #include "rtutil.tmh"
  19. //---------------------------------------------------------
  20. //
  21. // Function:
  22. // RTpGetQueuePropVar
  23. //
  24. // Description:
  25. // Find a queue property in the properties array
  26. //
  27. //---------------------------------------------------------
  28. PROPVARIANT*
  29. RTpGetQueuePropVar(
  30. PROPID PropID,
  31. MQQUEUEPROPS *pqp
  32. )
  33. {
  34. DWORD i;
  35. DWORD cProp;
  36. PROPID *aPropID;
  37. for (i = 0, cProp = pqp->cProp, aPropID = pqp->aPropID;
  38. i < cProp;
  39. i++, aPropID++) {
  40. if (*aPropID == PropID) {
  41. return(&(pqp->aPropVar[i]));
  42. }
  43. }
  44. return(NULL);
  45. }
  46. //---------------------------------------------------------
  47. //
  48. // Function:
  49. // RTpGetQueuePathNamePropVar
  50. //
  51. // Description:
  52. // Find a the queue path name property in the properties array
  53. //
  54. //---------------------------------------------------------
  55. LPWSTR
  56. RTpGetQueuePathNamePropVar(
  57. MQQUEUEPROPS *pqp
  58. )
  59. {
  60. PROPVARIANT *p;
  61. if ((p = RTpGetQueuePropVar(PROPID_Q_PATHNAME, pqp)) != NULL)
  62. return(p->pwszVal);
  63. else
  64. return(NULL);
  65. }
  66. //---------------------------------------------------------
  67. //
  68. // Function:
  69. // RTpGetQueueGuidPropVar
  70. //
  71. // Description:
  72. // Find the queue guid (instance) property in the properties array
  73. //
  74. //---------------------------------------------------------
  75. GUID*
  76. RTpGetQueueGuidPropVar(
  77. MQQUEUEPROPS *pqp
  78. )
  79. {
  80. PROPVARIANT *p;
  81. if ((p = RTpGetQueuePropVar(PROPID_Q_INSTANCE, pqp)) != NULL)
  82. return(p->puuid);
  83. else
  84. return(NULL);
  85. }
  86. //---------------------------------------------------------
  87. //
  88. // Function:
  89. // RTpMakeSelfRelativeSDAndGetSize
  90. //
  91. // Parameters:
  92. // pSecurityDescriptor - The input security descriptor.
  93. // pSelfRelativeSecurityDescriptor - A pointer to a temporary buffer
  94. // that holds the converted security descriptor.
  95. // pSDSize - A pointer to a variable that receives the length of the
  96. // self relative security descriptor. This is an optional parameter.
  97. //
  98. // Description:
  99. // Convert an absolute security descriptor to a self relative security
  100. // descriptor and get the size of the self relative security descriptor.
  101. // This function should be call before passing a security descriptor to
  102. // a function that passes the security descriptor to an RPC function.
  103. //
  104. // If the input security descriptor is already a self relative security
  105. // descriptor, the function only computes the length of the security
  106. // descriptor and returns. If the input security descriptor is an absolute
  107. // security descriptor, the function allocates a buffer large enough to
  108. // accomodate the self relative security descripr, converts the absolute
  109. // security descriptor to a self relative security descriptor and modifies
  110. // the pointer of the input security descriptor to point to the self relative
  111. // security descriptor.
  112. //
  113. // The temporar buffer that is being allocated for the self relative
  114. // security descriptor should be freed by the calling code.
  115. //
  116. //---------------------------------------------------------
  117. HRESULT
  118. RTpMakeSelfRelativeSDAndGetSize(
  119. PSECURITY_DESCRIPTOR *pSecurityDescriptor,
  120. PSECURITY_DESCRIPTOR *pSelfRelativeSecurityDescriptor,
  121. DWORD *pSDSize)
  122. {
  123. SECURITY_DESCRIPTOR_CONTROL sdcSDControl;
  124. DWORD dwSDRevision;
  125. ASSERT(pSecurityDescriptor);
  126. ASSERT(pSelfRelativeSecurityDescriptor);
  127. *pSelfRelativeSecurityDescriptor = NULL;
  128. if (!*pSecurityDescriptor)
  129. {
  130. // Set the security descriptor size.
  131. if (pSDSize)
  132. {
  133. *pSDSize = 0;
  134. }
  135. return(MQ_OK);
  136. }
  137. // Verify that this is a valid security descriptor.
  138. if (!IsValidSecurityDescriptor(*pSecurityDescriptor))
  139. {
  140. return(MQ_ERROR_ILLEGAL_SECURITY_DESCRIPTOR);
  141. }
  142. // Check whether this is a self relative or absolute security
  143. // descriptor.
  144. if (!GetSecurityDescriptorControl(*pSecurityDescriptor,
  145. &sdcSDControl,
  146. &dwSDRevision))
  147. {
  148. ASSERT(FALSE);
  149. }
  150. if (!(sdcSDControl & SE_SELF_RELATIVE))
  151. {
  152. // This is an absolute security descriptor, we should convert it
  153. // to a self relative one.
  154. DWORD dwBufferLength = 0;
  155. #ifdef _DEBUG
  156. SetLastError(0);
  157. #endif
  158. // Get the buffer size.
  159. MakeSelfRelativeSD(*pSecurityDescriptor, NULL, &dwBufferLength);
  160. ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
  161. // Allocate the buffer for the self relative security descriptor.
  162. *pSelfRelativeSecurityDescriptor =
  163. (PSECURITY_DESCRIPTOR) new char[dwBufferLength];
  164. // Convert the security descriptor.
  165. if (!MakeSelfRelativeSD(
  166. *pSecurityDescriptor,
  167. *pSelfRelativeSecurityDescriptor,
  168. &dwBufferLength))
  169. {
  170. ASSERT(FALSE);
  171. }
  172. ASSERT(IsValidSecurityDescriptor(*pSelfRelativeSecurityDescriptor));
  173. *pSecurityDescriptor = *pSelfRelativeSecurityDescriptor;
  174. // Set the security descriptor size.
  175. if (pSDSize)
  176. {
  177. *pSDSize = dwBufferLength;
  178. }
  179. }
  180. else
  181. {
  182. // The security descriptor is already in self relative format, just
  183. // set the security descriptor size.
  184. if (pSDSize)
  185. {
  186. *pSDSize = GetSecurityDescriptorLength(*pSecurityDescriptor);
  187. }
  188. }
  189. return(MQ_OK);
  190. }
  191. //---------------------------------------------------------
  192. //
  193. // Function:
  194. // RTpConvertToMQCode
  195. //
  196. // Parameters:
  197. // hr - Error vode that is generated by any kind of module.
  198. //
  199. // Return value:
  200. // The imput parameter convetrted to some equivalent MQ_ERROR constant.
  201. //
  202. //---------------------------------------------------------
  203. HRESULT
  204. RTpConvertToMQCode(
  205. HRESULT hr,
  206. DWORD dwObjectType
  207. )
  208. {
  209. if ((hr == MQ_OK) ||
  210. (hr == MQ_INFORMATION_REMOTE_OPERATION) ||
  211. (hr == MQ_ERROR_Q_DNS_PROPERTY_NOT_SUPPORTED) ||
  212. ((MQ_E_BASE <= hr) && (hr < MQ_E_BASE + 0x100)) ||
  213. ((MQ_I_BASE <= hr) && (hr < MQ_I_BASE + 0x100)))
  214. {
  215. // This is our codes, do not modify it.
  216. return(hr);
  217. }
  218. if (hr == MQDS_OK_REMOTE)
  219. {
  220. //
  221. // success - we use MQDS_OK_REMOTE for internal use, e.g. explorer
  222. //
  223. return(MQ_OK);
  224. }
  225. if (HRESULT_FACILITY(MQ_E_BASE) == HRESULT_FACILITY(hr))
  226. {
  227. switch (hr)
  228. {
  229. case MQDB_E_NO_MORE_DATA:
  230. case MQDS_GET_PROPERTIES_ERROR:
  231. case MQDS_OBJECT_NOT_FOUND:
  232. hr = (dwObjectType == MQDS_QUEUE) ?
  233. MQ_ERROR_QUEUE_NOT_FOUND :
  234. MQ_ERROR_MACHINE_NOT_FOUND;
  235. break;
  236. case MQDS_NO_RSP_FROM_OWNER:
  237. hr = MQ_ERROR_NO_RESPONSE_FROM_OBJECT_SERVER;
  238. break;
  239. case MQDS_OWNER_NOT_REACHED:
  240. hr = MQ_ERROR_OBJECT_SERVER_NOT_AVAILABLE;
  241. break;
  242. case MQDB_E_NON_UNIQUE_SORT:
  243. hr = MQ_ERROR_ILLEGAL_SORT;
  244. break;
  245. default:
  246. // Some DS error occured. This should not happen, but anyway...
  247. DBGMSG((DBGMOD_API, DBGLVL_WARNING,
  248. TEXT("A DS error (%x) has propagated to the RT DLL. Converting to MQ_ERROR_DS_ERROR"), hr));
  249. hr = MQ_ERROR_DS_ERROR;
  250. break;
  251. }
  252. return(hr);
  253. }
  254. if (hr == CPP_EXCEPTION_CODE)
  255. {
  256. // A C++ exception occured. This can happen only when in an allocation failure.
  257. return(MQ_ERROR_INSUFFICIENT_RESOURCES);
  258. }
  259. // Now we hope that we know how to convert an NTSTATUS to some of our error
  260. // codes. Good luck...
  261. switch(hr)
  262. {
  263. case STATUS_INVALID_HANDLE:
  264. case STATUS_OBJECT_TYPE_MISMATCH:
  265. hr = MQ_ERROR_INVALID_HANDLE;
  266. break;
  267. case STATUS_ACCESS_DENIED:
  268. hr = MQ_ERROR_ACCESS_DENIED;
  269. break;
  270. case STATUS_ACCESS_VIOLATION:
  271. case STATUS_INVALID_PARAMETER:
  272. hr = MQ_ERROR_INVALID_PARAMETER;
  273. break;
  274. case STATUS_SHARING_VIOLATION:
  275. hr = MQ_ERROR_SHARING_VIOLATION;
  276. break;
  277. case STATUS_PENDING:
  278. hr = MQ_INFORMATION_OPERATION_PENDING;
  279. break;
  280. case STATUS_CANCELLED:
  281. hr = MQ_ERROR_OPERATION_CANCELLED;
  282. break;
  283. case STATUS_INSUFFICIENT_RESOURCES:
  284. hr = MQ_ERROR_INSUFFICIENT_RESOURCES;
  285. break;
  286. case STATUS_INVALID_DEVICE_REQUEST:
  287. hr = MQ_ERROR_SERVICE_NOT_AVAILABLE;
  288. break;
  289. default:
  290. DBGMSG((DBGMOD_API, DBGLVL_WARNING,
  291. TEXT("Unfamiliar error code:%x, not converted to a MQ error"), hr));
  292. break;
  293. }
  294. return(hr);
  295. }
  296. //---------------------------------------------------------
  297. //
  298. // Function:
  299. // RTpGetThreadUserSid
  300. //
  301. // Parameters:
  302. // pUserSid - A pointer to a buffer that receives the address of a buffer
  303. // that contains the SID of the user of the current thread.
  304. // pdwUserSidLen - A pointer to a DWORD that receives the length of the
  305. // SID.
  306. //
  307. // Description:
  308. // The function allocates the buffer for the SID and fils it with the SID
  309. // of the user of the current thread. The calling code is responsible for
  310. // freeing the allocated buffer.
  311. //
  312. //---------------------------------------------------------
  313. HRESULT
  314. RTpGetThreadUserSid( BOOL *pfLocalUser,
  315. BOOL *pfLocalSystem,
  316. LPBYTE *pUserSid,
  317. DWORD *pdwUserSidLen )
  318. {
  319. HRESULT hr;
  320. hr = MQSec_GetUserType( NULL,
  321. pfLocalUser,
  322. pfLocalSystem );
  323. if (FAILED(hr))
  324. {
  325. return(hr);
  326. }
  327. if (*pfLocalSystem)
  328. {
  329. *pUserSid = (LPBYTE) MQSec_GetLocalMachineSid( TRUE, // allocate
  330. pdwUserSidLen ) ;
  331. if (!(*pUserSid))
  332. {
  333. //
  334. // this may happen if the machine belong to a NT4 domain
  335. // and it doesn't have any computer account and sid.
  336. // In that case, make it a local user.
  337. //
  338. ASSERT(*pdwUserSidLen == 0) ;
  339. *pdwUserSidLen = 0 ;
  340. *pfLocalSystem = FALSE ;
  341. if (pfLocalUser)
  342. {
  343. ASSERT(!(*pfLocalUser)) ;
  344. *pfLocalUser = TRUE ;
  345. }
  346. }
  347. }
  348. else if (!(*pfLocalUser))
  349. {
  350. hr = GetThreadUserSid(pUserSid, pdwUserSidLen);
  351. }
  352. return(hr);
  353. }