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.

409 lines
11 KiB

  1. #ifndef _AUSRUTIL_H
  2. #define _AUSRUTIL_H
  3. #include <activeds.h>
  4. #include <lm.h>
  5. #include <lmapibuf.h>
  6. #include <lmshare.h>
  7. #ifndef ASSERT
  8. #define ASSERT assert
  9. #endif
  10. #ifndef WSTRING
  11. typedef std::wstring WSTRING; // Move to sbs6base.h
  12. #endif
  13. enum NameContextType
  14. {
  15. NAMECTX_SCHEMA = 0,
  16. NAMECTX_CONFIG = 1,
  17. NAMECTX_COUNT
  18. };
  19. // ----------------------------------------------------------------------------
  20. // GetADNamingContext()
  21. // ----------------------------------------------------------------------------
  22. inline HRESULT GetADNamingContext(NameContextType ctx, LPCWSTR* ppszContextDN)
  23. {
  24. const static LPCWSTR pszContextName[NAMECTX_COUNT] = { L"schemaNamingContext", L"configurationNamingContext"};
  25. static WSTRING strContextDN[NAMECTX_COUNT];
  26. HRESULT hr = S_OK;
  27. if (strContextDN[ctx].empty())
  28. {
  29. CComVariant var;
  30. CComPtr<IADs> pObj;
  31. hr = ADsGetObject(L"LDAP://rootDSE", IID_IADs, (void**)&pObj);
  32. if (SUCCEEDED(hr))
  33. {
  34. hr = pObj->Get(const_cast<LPWSTR>(pszContextName[ctx]), &var);
  35. if (SUCCEEDED(hr))
  36. {
  37. strContextDN[ctx] = var.bstrVal;
  38. *ppszContextDN = strContextDN[ctx].c_str();
  39. }
  40. }
  41. }
  42. else
  43. {
  44. *ppszContextDN = strContextDN[ctx].c_str();
  45. hr = S_OK;
  46. }
  47. return hr;
  48. }
  49. //--------------------------------------------------------------------------
  50. // EnableButton
  51. //
  52. // Enables or disables a dialog control. If the control has the focus when
  53. // it is disabled, the focus is moved to the next control
  54. //--------------------------------------------------------------------------
  55. inline void EnableButton(HWND hwndDialog, int iCtrlID, BOOL bEnable)
  56. {
  57. HWND hWndCtrl = ::GetDlgItem(hwndDialog, iCtrlID);
  58. ATLASSERT(::IsWindow(hWndCtrl));
  59. if (!bEnable && ::GetFocus() == hWndCtrl)
  60. {
  61. HWND hWndNextCtrl = ::GetNextDlgTabItem(hwndDialog, hWndCtrl, FALSE);
  62. if (hWndNextCtrl != NULL && hWndNextCtrl != hWndCtrl)
  63. {
  64. ::SetFocus(hWndNextCtrl);
  65. }
  66. }
  67. ::EnableWindow(hWndCtrl, bEnable);
  68. }
  69. // ----------------------------------------------------------------------------
  70. // UserExists()
  71. // ----------------------------------------------------------------------------
  72. inline BOOL UserExists( const TCHAR *szUser )
  73. {
  74. _ASSERT(szUser);
  75. if ( !szUser )
  76. return FALSE;
  77. CComPtr<IADsUser> spADs = NULL;
  78. if ( FAILED(ADsGetObject(szUser, IID_IADsUser, (void**)&spADs)) )
  79. {
  80. return FALSE;
  81. }
  82. return TRUE;
  83. }
  84. // ----------------------------------------------------------------------------
  85. // BDirExists()
  86. // ----------------------------------------------------------------------------
  87. inline BOOL BDirExists( const TCHAR *szDir )
  88. {
  89. if (!szDir || !_tcslen( szDir ))
  90. return FALSE;
  91. DWORD dw = GetFileAttributes( szDir );
  92. if (dw != -1)
  93. {
  94. if (dw & FILE_ATTRIBUTE_DIRECTORY)
  95. return TRUE;
  96. }
  97. return FALSE;
  98. }
  99. // ----------------------------------------------------------------------------
  100. // IsValidNetHF()
  101. //
  102. // Checks to make sure that the path specified by szPath is a valid network
  103. // path (a return of 0 == success).
  104. //
  105. // 1 = IDS_ERROR_HF_INVALID
  106. // 2 = IDS_ERROR_HF_BADSRV
  107. // 4 = IDS_ERROR_HF_BADSHARE
  108. // 8 = IDS_ERROR_HF_PERMS
  109. //
  110. // ----------------------------------------------------------------------------
  111. inline INT IsValidNetHF( LPCTSTR szPath )
  112. {
  113. INT iRetVal = 0;
  114. DWORD dwError = 0;
  115. TCHAR szNetPath[MAX_PATH*5];
  116. TCHAR *pszServer = NULL;
  117. TCHAR *pszShare = NULL;
  118. WCHAR *pch = NULL; // Making this WCHAR instead of TCHAR because
  119. // with the pointer stepping below, it wouldn't
  120. // work as a regular CHAR (because of DBCS).
  121. TCHAR szCurrDir[MAX_PATH*2];
  122. INT iDirLen = MAX_PATH*2;
  123. _tcsncpy(szNetPath, szPath, (MAX_PATH*5)-1);
  124. // Make sure it at least starts off okay.
  125. if ( (_tcslen(szNetPath) < 6) ||
  126. (szNetPath[0] != _T('\\')) ||
  127. (szNetPath[1] != _T('\\')) ||
  128. (szNetPath[2] == _T('\\')) )
  129. return(1);
  130. // Make sure there's a server and share at least.
  131. pszServer = &szNetPath[2];
  132. if ( (pch = _tcschr(pszServer, _T('\\'))) == NULL )
  133. return 1;
  134. *pch++ = 0;
  135. pszShare = pch;
  136. if ( pch = _tcschr(pszShare, _T('\\')) )
  137. *pch = 0;
  138. if ( !_tcslen(pszServer) || !_tcslen(pszShare) )
  139. return 1;
  140. PSHARE_INFO_2 pShrInfo2 = NULL;
  141. NET_API_STATUS nApi = ERROR_SUCCESS;
  142. nApi = ::NetShareGetInfo( pszServer, pszShare, 2, (LPBYTE*)&pShrInfo2 );
  143. if ( pShrInfo2 )
  144. NetApiBufferFree(pShrInfo2);
  145. if ( nApi == ERROR_ACCESS_DENIED )
  146. return 8;
  147. else if ( nApi == NERR_NetNameNotFound )
  148. return 4;
  149. else if ( nApi != NERR_Success )
  150. return 2;
  151. /*
  152. // Let's try the szPath as is...
  153. if ( !::GetCurrentDirectory(iDirLen, szCurrDir) )
  154. return 0;
  155. if ( ::SetCurrentDirectory(szPath) )
  156. {
  157. ::SetCurrentDirectory(szCurrDir);
  158. }
  159. else
  160. {
  161. dwError = GetLastError();
  162. ::SetCurrentDirectory(szCurrDir);
  163. if ( (dwError == ERROR_FILE_NOT_FOUND) ||
  164. (dwError == ERROR_PATH_NOT_FOUND) )
  165. {
  166. return 4;
  167. }
  168. else if ( dwError == ERROR_ACCESS_DENIED )
  169. {
  170. return 8;
  171. }
  172. else
  173. {
  174. return 2;
  175. }
  176. }
  177. */
  178. _tcsncpy(szNetPath, szPath, (MAX_PATH*5)-1); // Take the passed in string.
  179. if ( szNetPath[_tcslen(szNetPath)] != _T('\\') )
  180. _tcscat(szNetPath, _T("\\"));
  181. _tcscat(szNetPath, _T("tedrtest")); // add a random path onto it.
  182. if ( ::SetCurrentDirectory(szNetPath) ) // Try setting to this new path.
  183. {
  184. ::SetCurrentDirectory(szCurrDir);
  185. return 0;
  186. }
  187. else
  188. {
  189. dwError = GetLastError();
  190. ::SetCurrentDirectory(szCurrDir);
  191. if ( dwError == ERROR_ACCESS_DENIED ) // Did we get access denied? Then we don't have
  192. { // access to the original share.
  193. return 8;
  194. }
  195. }
  196. return(iRetVal);
  197. }
  198. inline BOOL StrContainsDBCS(LPCTSTR szIn)
  199. {
  200. BOOL bFound = FALSE;
  201. TCHAR *pch = NULL;
  202. for ( pch=(LPTSTR)szIn; *pch && !bFound; pch=_tcsinc(pch) )
  203. {
  204. if ( IsDBCSLeadByte((BYTE)*pch) )
  205. bFound = TRUE;
  206. }
  207. return(bFound);
  208. }
  209. inline BOOL LdapToDCName(LPCTSTR pszPath, LPTSTR pszOutBuf, int nOutBufSize)
  210. {
  211. _ASSERT(pszPath != NULL && pszOutBuf != NULL && nOutBufSize != NULL);
  212. int nPathLen = _tcslen(pszPath);
  213. // alloc temp buffer that is guaranteed to be big enough (worst case = all chars must be escaped)
  214. LPTSTR pszLocBuf = (LPTSTR)alloca(_tcslen(pszPath) * sizeof(TCHAR) * 2);
  215. LPTSTR pszOut = pszLocBuf;
  216. LPCTSTR pszFirstDC = NULL;
  217. LPCTSTR psz;
  218. // Copy All DCs to buffer separated by periods
  219. if (nPathLen > 3)
  220. {
  221. // start search two chars from the start, so DC test doesn't go beyond start
  222. psz = pszPath + 2;
  223. while (psz = _tcschr(psz, L'='))
  224. {
  225. // if this is a DC name
  226. if (_tcsnicmp(psz - 2, L"DC", 2) == 0)
  227. {
  228. // Save pointer to first one
  229. if (pszFirstDC == NULL)
  230. pszFirstDC = psz - 2;
  231. // Copy name to ouput buffer
  232. psz++;
  233. while (*psz != TEXT(',') && *psz != 0)
  234. *pszOut++ = *psz++;
  235. // if not last one, add a '.'
  236. if (*psz != 0)
  237. *pszOut++ = TEXT('.');
  238. }
  239. else
  240. {
  241. // move past the current '='
  242. psz++;
  243. }
  244. }
  245. }
  246. // Add terminator
  247. *pszOut = 0;
  248. // Transfer converted path to real output buffer
  249. if (pszOut - pszLocBuf < nOutBufSize)
  250. {
  251. _tcscpy(pszOutBuf, pszLocBuf);
  252. return TRUE;
  253. }
  254. else
  255. {
  256. _tcsncpy(pszOutBuf, pszLocBuf, nOutBufSize - 1);
  257. pszOutBuf[nOutBufSize - 1] = 0;
  258. return FALSE;
  259. }
  260. }
  261. inline VARIANT GetDomainPath(LPCTSTR lpServer)
  262. {
  263. // get the domain information
  264. TCHAR pString[MAX_PATH*2];
  265. _stprintf(pString, L"LDAP://%s/rootDSE", lpServer);
  266. VARIANT vDomain;
  267. ::VariantInit(&vDomain);
  268. CComPtr<IADs> pDS = NULL;
  269. HRESULT hr = ::ADsGetObject(pString,
  270. IID_IADs,
  271. (void**)&pDS);
  272. ATLASSERT(hr == ERROR_SUCCESS);
  273. if (hr != ERROR_SUCCESS)
  274. {
  275. return vDomain;
  276. }
  277. hr = pDS->Get(L"defaultNamingContext", &vDomain);
  278. ATLASSERT(hr == ERROR_SUCCESS);
  279. if (hr != ERROR_SUCCESS)
  280. {
  281. return vDomain;
  282. }
  283. return vDomain;
  284. }
  285. //+----------------------------------------------------------------------------
  286. //
  287. // Function: RemoveTrailingWhitespace
  288. //
  289. // Synopsis: Trailing white space is replaced by NULLs.
  290. //
  291. //-----------------------------------------------------------------------------
  292. inline void RemoveTrailingWhitespace(PTSTR ptz)
  293. {
  294. int nLen = _tcslen(ptz);
  295. while (nLen)
  296. {
  297. if (!iswspace(ptz[nLen - 1]))
  298. {
  299. return;
  300. }
  301. ptz[nLen - 1] = L'\0';
  302. nLen--;
  303. }
  304. }
  305. HRESULT GetMDBPath( WSTRING& csMailbox )
  306. {
  307. // Get Configuration context of directory
  308. LPCWSTR pszContextDN = NULL;
  309. HRESULT hr = GetADNamingContext(NAMECTX_CONFIG, &pszContextDN);
  310. if ( FAILED(hr) )
  311. return hr;
  312. // Reduce the scope of the search to beneath the Exchange object
  313. WSTRING strExchScope = L"LDAP://CN=Microsoft Exchange,CN=Services,";
  314. strExchScope += pszContextDN;
  315. CComPtr<IDirectorySearch>pDirSearch = NULL;
  316. hr = ::ADsOpenObject(strExchScope.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (void**)&pDirSearch);
  317. if ( FAILED(hr) )
  318. return hr;
  319. // Search for Exchange MDB's. There should only be one in an SBS installation.
  320. ADS_SEARCH_HANDLE hSearch;
  321. LPWSTR pszAttr = L"distinguishedName";
  322. hr = pDirSearch->ExecuteSearch(L"(objectClass=msExchPrivateMDB)", &pszAttr, 1, &hSearch);
  323. if ( FAILED(hr) )
  324. return hr;
  325. // Get first found object and return its distinguished name
  326. hr = pDirSearch->GetNextRow(hSearch);
  327. if ( hr == S_OK )
  328. {
  329. ADS_SEARCH_COLUMN col;
  330. hr = pDirSearch->GetColumn(hSearch, pszAttr, &col);
  331. if ( SUCCEEDED(hr) )
  332. {
  333. ASSERT(col.dwADsType == ADSTYPE_DN_STRING);
  334. csMailbox = col.pADsValues->CaseIgnoreString;
  335. pDirSearch->FreeColumn(&col);
  336. }
  337. }
  338. pDirSearch->CloseSearchHandle(hSearch);
  339. return hr;
  340. }
  341. #endif // _AUSRUTIL_H