/*++ Copyright (c) 1995 Microsoft Corporation Module Name: rtutil.cpp Abstract: Contains various utility functions. Author: Boaz Feldbaum (BoazF) Mar 5, 1996 Revision History: Erez Haba (erezh) 17-Jan-1997 --*/ #include "stdh.h" #include "acrt.h" #include #include #include <_secutil.h> #include #include "rtutil.tmh" //--------------------------------------------------------- // // Function: // RTpGetQueuePropVar // // Description: // Find a queue property in the properties array // //--------------------------------------------------------- PROPVARIANT* RTpGetQueuePropVar( PROPID PropID, MQQUEUEPROPS *pqp ) { DWORD i; DWORD cProp; PROPID *aPropID; for (i = 0, cProp = pqp->cProp, aPropID = pqp->aPropID; i < cProp; i++, aPropID++) { if (*aPropID == PropID) { return(&(pqp->aPropVar[i])); } } return(NULL); } //--------------------------------------------------------- // // Function: // RTpGetQueuePathNamePropVar // // Description: // Find a the queue path name property in the properties array // //--------------------------------------------------------- LPWSTR RTpGetQueuePathNamePropVar( MQQUEUEPROPS *pqp ) { PROPVARIANT *p; if ((p = RTpGetQueuePropVar(PROPID_Q_PATHNAME, pqp)) != NULL) return(p->pwszVal); else return(NULL); } //--------------------------------------------------------- // // Function: // RTpGetQueueGuidPropVar // // Description: // Find the queue guid (instance) property in the properties array // //--------------------------------------------------------- GUID* RTpGetQueueGuidPropVar( MQQUEUEPROPS *pqp ) { PROPVARIANT *p; if ((p = RTpGetQueuePropVar(PROPID_Q_INSTANCE, pqp)) != NULL) return(p->puuid); else return(NULL); } //--------------------------------------------------------- // // Function: // RTpMakeSelfRelativeSDAndGetSize // // Parameters: // pSecurityDescriptor - The input security descriptor. // pSelfRelativeSecurityDescriptor - A pointer to a temporary buffer // that holds the converted security descriptor. // pSDSize - A pointer to a variable that receives the length of the // self relative security descriptor. This is an optional parameter. // // Description: // Convert an absolute security descriptor to a self relative security // descriptor and get the size of the self relative security descriptor. // This function should be call before passing a security descriptor to // a function that passes the security descriptor to an RPC function. // // If the input security descriptor is already a self relative security // descriptor, the function only computes the length of the security // descriptor and returns. If the input security descriptor is an absolute // security descriptor, the function allocates a buffer large enough to // accomodate the self relative security descripr, converts the absolute // security descriptor to a self relative security descriptor and modifies // the pointer of the input security descriptor to point to the self relative // security descriptor. // // The temporar buffer that is being allocated for the self relative // security descriptor should be freed by the calling code. // //--------------------------------------------------------- HRESULT RTpMakeSelfRelativeSDAndGetSize( PSECURITY_DESCRIPTOR *pSecurityDescriptor, PSECURITY_DESCRIPTOR *pSelfRelativeSecurityDescriptor, DWORD *pSDSize) { SECURITY_DESCRIPTOR_CONTROL sdcSDControl; DWORD dwSDRevision; ASSERT(pSecurityDescriptor); ASSERT(pSelfRelativeSecurityDescriptor); *pSelfRelativeSecurityDescriptor = NULL; if (!*pSecurityDescriptor) { // Set the security descriptor size. if (pSDSize) { *pSDSize = 0; } return(MQ_OK); } // Verify that this is a valid security descriptor. if (!IsValidSecurityDescriptor(*pSecurityDescriptor)) { return(MQ_ERROR_ILLEGAL_SECURITY_DESCRIPTOR); } // Check whether this is a self relative or absolute security // descriptor. if (!GetSecurityDescriptorControl(*pSecurityDescriptor, &sdcSDControl, &dwSDRevision)) { ASSERT(FALSE); } if (!(sdcSDControl & SE_SELF_RELATIVE)) { // This is an absolute security descriptor, we should convert it // to a self relative one. DWORD dwBufferLength = 0; #ifdef _DEBUG SetLastError(0); #endif // Get the buffer size. MakeSelfRelativeSD(*pSecurityDescriptor, NULL, &dwBufferLength); ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER); // Allocate the buffer for the self relative security descriptor. *pSelfRelativeSecurityDescriptor = (PSECURITY_DESCRIPTOR) new char[dwBufferLength]; // Convert the security descriptor. if (!MakeSelfRelativeSD( *pSecurityDescriptor, *pSelfRelativeSecurityDescriptor, &dwBufferLength)) { ASSERT(FALSE); } ASSERT(IsValidSecurityDescriptor(*pSelfRelativeSecurityDescriptor)); *pSecurityDescriptor = *pSelfRelativeSecurityDescriptor; // Set the security descriptor size. if (pSDSize) { *pSDSize = dwBufferLength; } } else { // The security descriptor is already in self relative format, just // set the security descriptor size. if (pSDSize) { *pSDSize = GetSecurityDescriptorLength(*pSecurityDescriptor); } } return(MQ_OK); } //--------------------------------------------------------- // // Function: // RTpConvertToMQCode // // Parameters: // hr - Error vode that is generated by any kind of module. // // Return value: // The imput parameter convetrted to some equivalent MQ_ERROR constant. // //--------------------------------------------------------- HRESULT RTpConvertToMQCode( HRESULT hr, DWORD dwObjectType ) { if ((hr == MQ_OK) || (hr == MQ_INFORMATION_REMOTE_OPERATION) || (hr == MQ_ERROR_Q_DNS_PROPERTY_NOT_SUPPORTED) || ((MQ_E_BASE <= hr) && (hr < MQ_E_BASE + 0x100)) || ((MQ_I_BASE <= hr) && (hr < MQ_I_BASE + 0x100))) { // This is our codes, do not modify it. return(hr); } if (hr == MQDS_OK_REMOTE) { // // success - we use MQDS_OK_REMOTE for internal use, e.g. explorer // return(MQ_OK); } if (HRESULT_FACILITY(MQ_E_BASE) == HRESULT_FACILITY(hr)) { switch (hr) { case MQDB_E_NO_MORE_DATA: case MQDS_GET_PROPERTIES_ERROR: case MQDS_OBJECT_NOT_FOUND: hr = (dwObjectType == MQDS_QUEUE) ? MQ_ERROR_QUEUE_NOT_FOUND : MQ_ERROR_MACHINE_NOT_FOUND; break; case MQDS_NO_RSP_FROM_OWNER: hr = MQ_ERROR_NO_RESPONSE_FROM_OBJECT_SERVER; break; case MQDS_OWNER_NOT_REACHED: hr = MQ_ERROR_OBJECT_SERVER_NOT_AVAILABLE; break; case MQDB_E_NON_UNIQUE_SORT: hr = MQ_ERROR_ILLEGAL_SORT; break; default: // Some DS error occured. This should not happen, but anyway... DBGMSG((DBGMOD_API, DBGLVL_WARNING, TEXT("A DS error (%x) has propagated to the RT DLL. Converting to MQ_ERROR_DS_ERROR"), hr)); hr = MQ_ERROR_DS_ERROR; break; } return(hr); } if (hr == CPP_EXCEPTION_CODE) { // A C++ exception occured. This can happen only when in an allocation failure. return(MQ_ERROR_INSUFFICIENT_RESOURCES); } // Now we hope that we know how to convert an NTSTATUS to some of our error // codes. Good luck... switch(hr) { case STATUS_INVALID_HANDLE: case STATUS_OBJECT_TYPE_MISMATCH: hr = MQ_ERROR_INVALID_HANDLE; break; case STATUS_ACCESS_DENIED: hr = MQ_ERROR_ACCESS_DENIED; break; case STATUS_ACCESS_VIOLATION: case STATUS_INVALID_PARAMETER: hr = MQ_ERROR_INVALID_PARAMETER; break; case STATUS_SHARING_VIOLATION: hr = MQ_ERROR_SHARING_VIOLATION; break; case STATUS_PENDING: hr = MQ_INFORMATION_OPERATION_PENDING; break; case STATUS_CANCELLED: hr = MQ_ERROR_OPERATION_CANCELLED; break; case STATUS_INSUFFICIENT_RESOURCES: hr = MQ_ERROR_INSUFFICIENT_RESOURCES; break; case STATUS_INVALID_DEVICE_REQUEST: hr = MQ_ERROR_SERVICE_NOT_AVAILABLE; break; default: DBGMSG((DBGMOD_API, DBGLVL_WARNING, TEXT("Unfamiliar error code:%x, not converted to a MQ error"), hr)); break; } return(hr); } //--------------------------------------------------------- // // Function: // RTpGetThreadUserSid // // Parameters: // pUserSid - A pointer to a buffer that receives the address of a buffer // that contains the SID of the user of the current thread. // pdwUserSidLen - A pointer to a DWORD that receives the length of the // SID. // // Description: // The function allocates the buffer for the SID and fils it with the SID // of the user of the current thread. The calling code is responsible for // freeing the allocated buffer. // //--------------------------------------------------------- HRESULT RTpGetThreadUserSid( BOOL *pfLocalUser, BOOL *pfLocalSystem, LPBYTE *pUserSid, DWORD *pdwUserSidLen ) { HRESULT hr; hr = MQSec_GetUserType( NULL, pfLocalUser, pfLocalSystem ); if (FAILED(hr)) { return(hr); } if (*pfLocalSystem) { *pUserSid = (LPBYTE) MQSec_GetLocalMachineSid( TRUE, // allocate pdwUserSidLen ) ; if (!(*pUserSid)) { // // this may happen if the machine belong to a NT4 domain // and it doesn't have any computer account and sid. // In that case, make it a local user. // ASSERT(*pdwUserSidLen == 0) ; *pdwUserSidLen = 0 ; *pfLocalSystem = FALSE ; if (pfLocalUser) { ASSERT(!(*pfLocalUser)) ; *pfLocalUser = TRUE ; } } } else if (!(*pfLocalUser)) { hr = GetThreadUserSid(pUserSid, pdwUserSidLen); } return(hr); }