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.

237 lines
5.1 KiB

  1. //
  2. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. #include "precomp.h"
  5. CNamesList :: CNamesList()
  6. {
  7. m_pListOfClassNames = NULL;
  8. m_dwElementCount = 0;
  9. InitializeCriticalSection(&m_AccessibleClassesSection);
  10. }
  11. CNamesList :: ~CNamesList()
  12. {
  13. EnterCriticalSection(&m_AccessibleClassesSection);
  14. CLPWSTR *pTemp1 = m_pListOfClassNames;
  15. CLPWSTR *pNext = m_pListOfClassNames;
  16. while(pTemp1)
  17. {
  18. pNext = pTemp1->pNext;
  19. delete pTemp1;
  20. pTemp1 = pNext;
  21. }
  22. LeaveCriticalSection(&m_AccessibleClassesSection);
  23. DeleteCriticalSection(&m_AccessibleClassesSection);
  24. }
  25. BOOLEAN CNamesList :: IsNamePresent(LPCWSTR pszClassName)
  26. {
  27. // Get the current impersonation level
  28. DWORD dwCurrentImpersonationLevel = 0;
  29. if(FAILED(GetImpersonationLevel(&dwCurrentImpersonationLevel)))
  30. return FALSE;
  31. // Look for a name in the list that has an impersonation level of current or greater
  32. BOOLEAN bRetVal = FALSE;
  33. EnterCriticalSection(&m_AccessibleClassesSection);
  34. CLPWSTR *pCurrent = m_pListOfClassNames;
  35. while(pCurrent)
  36. {
  37. if(_wcsicmp(pCurrent->pszVal, pszClassName) == 0 && pCurrent->dwImpersonationLevel <= dwCurrentImpersonationLevel)
  38. {
  39. bRetVal = TRUE;
  40. break;
  41. }
  42. pCurrent = pCurrent->pNext;
  43. }
  44. LeaveCriticalSection(&m_AccessibleClassesSection);
  45. return bRetVal;
  46. }
  47. BOOLEAN CNamesList :: RemoveName(LPCWSTR pszClassName)
  48. {
  49. #ifdef NO_WBEM_CACHE
  50. return FALSE;
  51. #else
  52. BOOLEAN bRetVal = FALSE;
  53. EnterCriticalSection(&m_AccessibleClassesSection);
  54. if(m_pListOfClassNames)
  55. {
  56. // Is it the first node ?
  57. if(_wcsicmp(m_pListOfClassNames->pszVal, pszClassName) == 0)
  58. {
  59. bRetVal = TRUE;
  60. CLPWSTR *pTemp = m_pListOfClassNames->pNext;
  61. delete m_pListOfClassNames;
  62. m_pListOfClassNames = pTemp;
  63. m_dwElementCount--;
  64. }
  65. else
  66. {
  67. CLPWSTR *pPrev = m_pListOfClassNames;
  68. CLPWSTR *pCurrent = m_pListOfClassNames->pNext;
  69. while(pCurrent)
  70. {
  71. if(_wcsicmp(pCurrent->pszVal, pszClassName) == 0)
  72. {
  73. bRetVal = TRUE;
  74. pPrev->pNext = pCurrent->pNext;
  75. delete pCurrent;
  76. m_dwElementCount --;
  77. break;
  78. }
  79. pPrev = pCurrent;
  80. pCurrent = pCurrent->pNext;
  81. }
  82. }
  83. }
  84. LeaveCriticalSection(&m_AccessibleClassesSection);
  85. return bRetVal;
  86. #endif
  87. }
  88. BOOLEAN CNamesList :: AddName(LPCWSTR pszClassName)
  89. {
  90. #ifdef NO_WBEM_CACHE
  91. return FALSE;
  92. #else
  93. // Get the current impersonation level
  94. DWORD dwCurrentImpersonationLevel = 0;
  95. if(!SUCCEEDED(GetImpersonationLevel(&dwCurrentImpersonationLevel)))
  96. return FALSE;
  97. // Add it only if it doesnt already exist in the list
  98. BOOLEAN bFound = FALSE;
  99. EnterCriticalSection(&m_AccessibleClassesSection);
  100. CLPWSTR *pCurrent = m_pListOfClassNames;
  101. while(pCurrent)
  102. {
  103. if(_wcsicmp(pCurrent->pszVal, pszClassName) == 0)
  104. {
  105. bFound = TRUE;
  106. break;
  107. }
  108. pCurrent = pCurrent->pNext;
  109. }
  110. // Add it at the head
  111. if(!bFound)
  112. {
  113. pCurrent = m_pListOfClassNames;
  114. m_pListOfClassNames = new CLPWSTR;
  115. m_pListOfClassNames->pszVal = new WCHAR[wcslen(pszClassName) + 1];
  116. m_pListOfClassNames->dwImpersonationLevel = dwCurrentImpersonationLevel;
  117. wcscpy(m_pListOfClassNames->pszVal, pszClassName);
  118. m_pListOfClassNames->pNext = pCurrent;
  119. m_dwElementCount ++;
  120. }
  121. else // update the impersonation level if necessary
  122. {
  123. if(pCurrent->dwImpersonationLevel < dwCurrentImpersonationLevel)
  124. pCurrent->dwImpersonationLevel = dwCurrentImpersonationLevel;
  125. }
  126. LeaveCriticalSection(&m_AccessibleClassesSection);
  127. return !bFound;
  128. #endif
  129. }
  130. DWORD CNamesList :: GetAllNames(LPWSTR **pppszNames)
  131. {
  132. EnterCriticalSection(&m_AccessibleClassesSection);
  133. DWORD retVal = m_dwElementCount;
  134. *pppszNames = NULL;
  135. if(m_dwElementCount)
  136. {
  137. if(*pppszNames = new LPWSTR[m_dwElementCount])
  138. {
  139. CLPWSTR *pCurrent = m_pListOfClassNames;
  140. bool bError = false;
  141. for(DWORD i=0; !bError && (i<m_dwElementCount); i++)
  142. {
  143. (*pppszNames)[i] = NULL;
  144. if((*pppszNames)[i] = new WCHAR[wcslen(pCurrent->pszVal) + 1])
  145. {
  146. wcscpy((*pppszNames)[i], pCurrent->pszVal);
  147. pCurrent = pCurrent->pNext;
  148. }
  149. else
  150. bError = true;
  151. }
  152. if(bError)
  153. {
  154. retVal = 0;
  155. delete [] (*pppszNames);
  156. *pppszNames = NULL;
  157. }
  158. }
  159. else
  160. retVal = 0;
  161. }
  162. LeaveCriticalSection(&m_AccessibleClassesSection);
  163. return retVal;
  164. }
  165. HRESULT CNamesList :: GetImpersonationLevel(DWORD *pdwImpLevel)
  166. {
  167. //get implevel...
  168. HANDLE hThreadTok = NULL;
  169. HRESULT hr = E_FAIL;
  170. if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hThreadTok) )
  171. {
  172. DWORD dwBytesReturned = 0;
  173. DWORD dwThreadImpLevel = 0;
  174. if (GetTokenInformation(hThreadTok, TokenImpersonationLevel, &dwThreadImpLevel,
  175. sizeof(DWORD), &dwBytesReturned))
  176. {
  177. hr = S_OK;
  178. switch(dwThreadImpLevel)
  179. {
  180. case SecurityAnonymous:
  181. {
  182. *pdwImpLevel = RPC_C_IMP_LEVEL_ANONYMOUS;
  183. }
  184. break;
  185. case SecurityIdentification:
  186. {
  187. *pdwImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
  188. }
  189. break;
  190. case SecurityImpersonation:
  191. {
  192. *pdwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  193. }
  194. break;
  195. case SecurityDelegation:
  196. {
  197. *pdwImpLevel = RPC_C_IMP_LEVEL_DELEGATE;
  198. }
  199. break;
  200. default:
  201. {
  202. hr = E_FAIL;
  203. }
  204. }
  205. }
  206. CloseHandle(hThreadTok);
  207. }
  208. return hr;
  209. }