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.

908 lines
18 KiB

  1. /* ----------------------------------------------------------------------
  2. Module: ULS.DLL (Service Provider)
  3. File: sputils.cpp
  4. Content: This file contains the utilities for service provider.
  5. History:
  6. 10/15/96 Chu, Lon-Chan [lonchanc]
  7. Created.
  8. Copyright (c) Microsoft Corporation 1996-1997
  9. ---------------------------------------------------------------------- */
  10. #include "ulsp.h"
  11. #include "spinc.h"
  12. TCHAR c_szWindowClassName[] = TEXT ("UlsLdapSp");
  13. BOOL g_fExitNow = FALSE;
  14. HANDLE g_ahThreadWaitFor[NUM_THREAD_WAIT_FOR] = { 0 };
  15. DWORD WINAPI
  16. ReqThread ( VOID *lParam )
  17. {
  18. BOOL fStayInThisThread = TRUE;
  19. DWORD dwExitCode = 0;
  20. DWORD dwResult;
  21. // Start WSA for subsequent host query in this service provider
  22. //
  23. WSADATA WSAData;
  24. if (WSAStartup (MAKEWORD (1, 1), &WSAData))
  25. {
  26. dwExitCode = ILS_E_WINSOCK;
  27. goto MyExit;
  28. }
  29. // Make sure that all the event are initialized
  30. //
  31. INT i;
  32. for (i = 0; i < NUM_THREAD_WAIT_FOR; i++)
  33. {
  34. if (g_ahThreadWaitFor[i] == NULL)
  35. {
  36. MyAssert (FALSE);
  37. dwExitCode = ILS_E_THREAD;
  38. goto MyExit;
  39. }
  40. }
  41. // Wait for events to happen!!!
  42. //
  43. do
  44. {
  45. dwResult = MsgWaitForMultipleObjects ( NUM_THREAD_WAIT_FOR,
  46. &g_ahThreadWaitFor[0],
  47. FALSE, // OR logic
  48. INFINITE, // infinite
  49. QS_ALLINPUT); // any message in queue
  50. switch (dwResult)
  51. {
  52. case WAIT_OBJECT_0 + THREAD_WAIT_FOR_REQUEST:
  53. if (g_pReqQueue != NULL)
  54. {
  55. g_pReqQueue->Schedule ();
  56. MyAssert (fStayInThisThread);
  57. }
  58. else
  59. {
  60. MyAssert (FALSE);
  61. fStayInThisThread = FALSE;
  62. }
  63. break;
  64. case WAIT_OBJECT_0 + THREAD_WAIT_FOR_EXIT:
  65. case WAIT_ABANDONED_0 + THREAD_WAIT_FOR_EXIT:
  66. case WAIT_ABANDONED_0 + THREAD_WAIT_FOR_REQUEST:
  67. case WAIT_TIMEOUT:
  68. // Exit this thread
  69. //
  70. fStayInThisThread = FALSE;
  71. break;
  72. default:
  73. // If a message in the queue, then dispatch it.
  74. // Right now, wldap32 does not have a message pump.
  75. // However, for possible update of wldap32, we need to
  76. // protect ourselves from being fried.
  77. //
  78. if (! KeepUiResponsive ())
  79. fStayInThisThread = FALSE;
  80. break;
  81. }
  82. }
  83. while (fStayInThisThread);
  84. MyExit:
  85. if (dwExitCode != ILS_E_WINSOCK)
  86. WSACleanup ();
  87. // ExitThread (dwExitCode);
  88. return 0;
  89. }
  90. BOOL KeepUiResponsive ( VOID )
  91. {
  92. MSG msg;
  93. while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
  94. {
  95. if (msg.message != WM_QUIT)
  96. {
  97. TranslateMessage (&msg);
  98. DispatchMessage (&msg);
  99. }
  100. else
  101. {
  102. PostQuitMessage ((int)msg.wParam);
  103. return FALSE;
  104. }
  105. }
  106. return TRUE;
  107. }
  108. LRESULT CALLBACK
  109. SP_WndProc ( HWND hWnd, UINT uMsg, WPARAM uParam, LPARAM lParam )
  110. {
  111. switch (uMsg)
  112. {
  113. case WM_CREATE:
  114. break;
  115. case WM_TIMER:
  116. switch (LOWORD (uParam))
  117. {
  118. case ID_TIMER_POLL_RESULT:
  119. if (g_pRespQueue != NULL)
  120. {
  121. // No-wait polling
  122. //
  123. LDAP_TIMEVAL PollTimeout;
  124. ZeroMemory (&PollTimeout, sizeof (PollTimeout));
  125. // PollTimeout.tv_sec = 0;
  126. // PollTimeout.tv_usec = 0;
  127. g_pRespQueue->PollLdapResults (&PollTimeout);
  128. }
  129. else
  130. {
  131. MyAssert (FALSE);
  132. }
  133. break;
  134. default:
  135. if (LOWORD (uParam) >= KEEP_ALIVE_TIMER_BASE)
  136. {
  137. // Allocate marshall request buffer
  138. //
  139. MARSHAL_REQ *pReq = MarshalReq_Alloc (WM_ILS_REFRESH, 0, 1);
  140. if (pReq != NULL)
  141. {
  142. HRESULT hr = ILS_E_FAIL;
  143. ULONG uTimerID = LOWORD (uParam);
  144. // Fill in parameters
  145. //
  146. MarshalReq_SetParam (pReq, 0, (DWORD) uTimerID, 0);
  147. // Enter the request
  148. //
  149. if (g_pReqQueue != NULL)
  150. {
  151. hr = g_pReqQueue->Enter (pReq);
  152. }
  153. else
  154. {
  155. MyAssert (FALSE);
  156. }
  157. // Avoid timer overrun if the request is submitted successfully
  158. //
  159. if (hr == S_OK)
  160. {
  161. KillTimer (hWnd, uTimerID);
  162. }
  163. else
  164. {
  165. MemFree (pReq);
  166. }
  167. }
  168. }
  169. else
  170. {
  171. MyAssert (FALSE);
  172. }
  173. break;
  174. } // switch (LOWORD (uParam))
  175. break;
  176. case WM_ILS_CLIENT_NEED_RELOGON:
  177. case WM_ILS_CLIENT_NETWORK_DOWN:
  178. #if 1
  179. MyAssert (FALSE); // we should post to com directly
  180. #else
  181. {
  182. // Get the local user object
  183. //
  184. SP_CClient *pClient = (SP_CClient *) lParam;
  185. // Make sure the parent local user object is valid
  186. //
  187. if (MyIsBadWritePtr (pClient, sizeof (*pClient)) ||
  188. ! pClient->IsValidObject () ||
  189. ! pClient->IsRegistered ())
  190. {
  191. MyAssert (FALSE);
  192. break; // exit
  193. }
  194. // Indicate this user object is not remotely connected to the server
  195. //
  196. pClient->SetRegLocally ();
  197. // Get the server info
  198. //
  199. SERVER_INFO *pServerInfo = pClient->GetServerInfo ();
  200. if (pServerInfo == NULL)
  201. {
  202. MyAssert (FALSE);
  203. break; // exit
  204. }
  205. // Duplicate the server name
  206. //
  207. TCHAR *pszServerName = My_strdup (pServerInfo->pszServerName);
  208. if (pszServerName == NULL)
  209. break; // exit
  210. // Notify the com layer
  211. //
  212. PostMessage (g_hWndNotify, uMsg, (WPARAM) pClient, (LPARAM) pszServerName);
  213. }
  214. #endif
  215. break;
  216. #ifdef ENABLE_MEETING_PLACE
  217. case WM_ILS_MEETING_NEED_RELOGON:
  218. case WM_ILS_MEETING_NETWORK_DOWN:
  219. #if 1
  220. MyAssert (FALSE); // we should post to com directly
  221. #else
  222. {
  223. // Get the local user object
  224. //
  225. SP_CMeeting *pMtg = (SP_CMeeting *) lParam;
  226. // Make sure the parent local user object is valid
  227. //
  228. if (MyIsBadWritePtr (pMtg, sizeof (*pMtg)) ||
  229. ! pMtg->IsValidObject () ||
  230. ! pMtg->IsRegistered ())
  231. {
  232. MyAssert (FALSE);
  233. break; // exit
  234. }
  235. // Indicate this user object is not remotely connected to the server
  236. //
  237. pMtg->SetRegLocally ();
  238. // Get the server info
  239. //
  240. SERVER_INFO *pServerInfo = pMtg->GetServerInfo ();
  241. if (pServerInfo == NULL)
  242. {
  243. MyAssert (FALSE);
  244. break; // exit
  245. }
  246. // Duplicate the server name
  247. //
  248. TCHAR *pszServerName = My_strdup (pServerInfo->pszServerName);
  249. if (pszServerName == NULL)
  250. break; // exit
  251. // Notify the com layer
  252. //
  253. PostMessage (g_hWndNotify, uMsg, (WPARAM) pMtg, (LPARAM) pszServerName);
  254. }
  255. #endif
  256. break;
  257. #endif // ENABLE_MEETING_PLACE
  258. #if 0
  259. case WM_ILS_IP_ADDRESS_CHANGED:
  260. {
  261. // Get the local user object
  262. //
  263. SP_CClient *pClient = (SP_CClient *) lParam;
  264. // Make sure the parent local user object is valid
  265. //
  266. if (MyIsBadWritePtr (pClient, sizeof (*pClient)) ||
  267. ! pClient->IsValidObject () ||
  268. ! pClient->IsRegistered ())
  269. {
  270. MyAssert (FALSE);
  271. break; // exit
  272. }
  273. // Change IP address now
  274. //
  275. pClient->UpdateIPAddress ();
  276. }
  277. break;
  278. #endif
  279. case WM_CLOSE:
  280. DestroyWindow (hWnd);
  281. break;
  282. case WM_DESTROY:
  283. g_hWndHidden = NULL;
  284. #ifdef USE_HIDDEN_THREAD
  285. PostQuitMessage (0);
  286. #endif
  287. break;
  288. default:
  289. return DefWindowProc (hWnd, uMsg, uParam, lParam);
  290. }
  291. return 0;
  292. }
  293. BOOL MyCreateWindow ( VOID )
  294. {
  295. WNDCLASS wc;
  296. // do the stuff to create a hidden window
  297. ZeroMemory (&wc, sizeof (wc));
  298. // wc.style = 0;
  299. wc.lpfnWndProc = SP_WndProc;
  300. // wc.cbClsExtra = 0;
  301. // wc.cbWndExtra = 0;
  302. // wc.hIcon = NULL;
  303. wc.hInstance = g_hInstance;
  304. // wc.hCursor = NULL;
  305. // wc.hbrBackground = NULL;
  306. // wc.lpszMenuName = NULL;
  307. wc.lpszClassName = c_szWindowClassName;
  308. // register the class
  309. // it is ok, if the class is already registered by another app
  310. RegisterClass (&wc);
  311. // create a window for socket notification
  312. g_hWndHidden = CreateWindow (
  313. wc.lpszClassName,
  314. NULL,
  315. WS_POPUP, /* Window style. */
  316. CW_USEDEFAULT,
  317. CW_USEDEFAULT,
  318. CW_USEDEFAULT,
  319. CW_USEDEFAULT,
  320. NULL, /* the application window is the parent. */
  321. NULL, /* hardcoded ID */
  322. g_hInstance, /* the application owns this window. */
  323. NULL); /* Pointer not needed. */
  324. return (g_hWndHidden != NULL);
  325. }
  326. HRESULT
  327. GetLocalIPAddress ( DWORD *pdwIPAddress )
  328. {
  329. MyAssert (pdwIPAddress != NULL);
  330. // get local host name
  331. CHAR szLocalHostName[MAX_PATH];
  332. szLocalHostName[0] = '\0';
  333. gethostname (&szLocalHostName[0], MAX_PATH);
  334. // get the host entry by name
  335. PHOSTENT phe = gethostbyname (&szLocalHostName[0]);
  336. if (phe == NULL)
  337. return ILS_E_WINSOCK;
  338. // get info from the host entry
  339. *pdwIPAddress = *(DWORD *) phe->h_addr;
  340. return S_OK;
  341. }
  342. // guid --> string
  343. VOID
  344. GetGuidString ( GUID *pGuid, TCHAR *pszGuid )
  345. {
  346. MyAssert (! MyIsBadWritePtr (pGuid, sizeof (GUID)));
  347. MyAssert (pszGuid != NULL);
  348. CHAR *psz = (CHAR *) pGuid;
  349. for (ULONG i = 0; i < sizeof (GUID); i++)
  350. {
  351. wsprintf (pszGuid, TEXT ("%02x"), (0x0FF & (ULONG) *psz));
  352. pszGuid += 2;
  353. psz++;
  354. }
  355. *pszGuid = TEXT ('\0');
  356. }
  357. // string --> guid
  358. VOID
  359. GetStringGuid ( TCHAR *pszGuid, GUID *pGuid )
  360. {
  361. ULONG cchGuid = lstrlen (pszGuid);
  362. MyAssert (cchGuid == 2 * sizeof (GUID));
  363. MyAssert (! MyIsBadWritePtr (pGuid, sizeof (GUID)));
  364. // Clean up target GUID structure
  365. //
  366. ZeroMemory (pGuid, sizeof (GUID));
  367. // Translate guid string to guid
  368. //
  369. CHAR *psz = (CHAR *) pGuid;
  370. cchGuid >>= 1;
  371. for (ULONG i = 0; i < cchGuid; i++)
  372. {
  373. *psz++ = (CHAR) ((HexChar2Val (pszGuid[0]) << 4) |
  374. HexChar2Val (pszGuid[1]));
  375. pszGuid += 2;
  376. }
  377. }
  378. INT
  379. HexChar2Val ( TCHAR c )
  380. {
  381. INT Val;
  382. if (TEXT ('0') <= c && c <= TEXT ('9'))
  383. Val = c - TEXT ('0');
  384. else
  385. if (TEXT ('a') <= c && c <= TEXT ('f'))
  386. Val = c - TEXT ('a') + 10;
  387. else
  388. if (TEXT ('A') <= c && c <= TEXT ('F'))
  389. Val = c - TEXT ('A') + 10;
  390. else
  391. Val = 0;
  392. MyAssert (0 <= Val && Val <= 15);
  393. return Val & 0x0F;
  394. }
  395. INT
  396. DecimalChar2Val ( TCHAR c )
  397. {
  398. INT Val;
  399. if (TEXT ('0') <= c && c <= TEXT ('9'))
  400. Val = c - TEXT ('0');
  401. else
  402. Val = 0;
  403. MyAssert (0 <= Val && Val <= 9);
  404. return Val & 0x0F;
  405. }
  406. BOOL
  407. IsValidGuid ( GUID *pGuid )
  408. {
  409. DWORD *pdw = (DWORD *) pGuid;
  410. return (pdw[0] != 0 || pdw[1] != 0 || pdw[2] != 0 || pdw[3] != 0);
  411. }
  412. // long --> string
  413. VOID
  414. GetLongString ( LONG Val, TCHAR *pszVal )
  415. {
  416. MyAssert (pszVal != NULL);
  417. wsprintf (pszVal, TEXT ("%lu"), Val);
  418. }
  419. // string --> long
  420. LONG
  421. GetStringLong ( TCHAR *pszVal )
  422. {
  423. MyAssert (pszVal != NULL);
  424. LONG Val = 0;
  425. for (INT i = 0; i < INTEGER_STRING_LENGTH && *pszVal != TEXT ('\0'); i++)
  426. {
  427. Val = 10 * Val + DecimalChar2Val (*pszVal++);
  428. }
  429. return Val;
  430. }
  431. // it is the caller's responsibility to make sure
  432. // the buffer is sufficient and
  433. // the ip address is in network order
  434. VOID
  435. GetIPAddressString ( TCHAR *pszIPAddress, DWORD dwIPAddress )
  436. {
  437. BYTE temp[4];
  438. *(DWORD *) &temp[0] = dwIPAddress;
  439. wsprintf (pszIPAddress, TEXT ("%u.%u.%u.%u"),
  440. (UINT) temp[0], (UINT) temp[1],
  441. (UINT) temp[2], (UINT) temp[3]);
  442. }
  443. ULONG
  444. My_lstrlen ( const TCHAR *psz )
  445. {
  446. return ((psz != NULL) ? lstrlen (psz) : 0);
  447. }
  448. VOID
  449. My_lstrcpy ( TCHAR *pszDst, const TCHAR *pszSrc )
  450. {
  451. if (pszDst != NULL)
  452. {
  453. if (pszSrc != NULL)
  454. {
  455. lstrcpy (pszDst, pszSrc);
  456. }
  457. else
  458. {
  459. *pszDst = TEXT ('\0');
  460. }
  461. }
  462. }
  463. INT
  464. My_lstrcmpi ( const TCHAR *p, const TCHAR *q )
  465. {
  466. INT retcode;
  467. if (p == q)
  468. {
  469. retcode = 0;
  470. }
  471. else
  472. if (p == NULL)
  473. {
  474. retcode = -1;
  475. }
  476. else
  477. if (q == NULL)
  478. {
  479. retcode = 1;
  480. }
  481. else
  482. {
  483. retcode = lstrcmpi (p, q);
  484. }
  485. return retcode;
  486. }
  487. TCHAR *
  488. My_strdup ( const TCHAR *pszToDup )
  489. {
  490. TCHAR *psz = NULL;
  491. if (pszToDup != NULL)
  492. {
  493. psz = (TCHAR *) MemAlloc ((lstrlen (pszToDup) + 1) * sizeof (TCHAR));
  494. if (psz != NULL)
  495. {
  496. lstrcpy (psz, pszToDup);
  497. }
  498. }
  499. return psz;
  500. }
  501. TCHAR *
  502. My_strchr ( const TCHAR *psz, TCHAR c )
  503. {
  504. TCHAR *pszFound = NULL;
  505. if (psz)
  506. {
  507. while (*psz)
  508. {
  509. if (*psz == c)
  510. {
  511. pszFound = (TCHAR *) psz;
  512. break;
  513. }
  514. psz++;
  515. }
  516. }
  517. return pszFound;
  518. }
  519. BOOL
  520. My_isspace ( TCHAR ch )
  521. {
  522. return (ch == TEXT (' ') || ch == TEXT ('\t') ||
  523. ch == TEXT ('\r') || ch == TEXT ('\n'));
  524. }
  525. BOOL
  526. IsSameMemory ( const BYTE *pb1, const BYTE *pb2, DWORD cbSize )
  527. {
  528. while (cbSize--)
  529. {
  530. if (*pb1++ != *pb2++)
  531. {
  532. return FALSE;
  533. }
  534. }
  535. return TRUE;
  536. }
  537. BYTE *
  538. MyBinDup ( const BYTE *pbToDup, ULONG cbToDup )
  539. {
  540. BYTE *pb = NULL;
  541. if (pbToDup)
  542. {
  543. pb = (BYTE *) MemAlloc (cbToDup);
  544. if (pb)
  545. {
  546. CopyMemory (pb, pbToDup, cbToDup);
  547. }
  548. }
  549. return pb;
  550. }
  551. /* ---------- registry ------------- */
  552. const TCHAR c_szUlsLdapSpReg[] = TEXT("Software\\Microsoft\\User Location Service\\LDAP Provider");
  553. const TCHAR c_szResponseTimeout[] = TEXT("Response Timeout");
  554. const TCHAR c_szResponsePollPeriod[] = TEXT("Response Poll Period");
  555. const TCHAR c_szClientSig[] = TEXT ("Client Signature");
  556. BOOL
  557. GetRegistrySettings ( VOID )
  558. {
  559. // Open the LDAP Provider settings
  560. //
  561. HKEY hKey;
  562. if (RegOpenKeyEx ( HKEY_CURRENT_USER,
  563. &c_szUlsLdapSpReg[0],
  564. 0,
  565. KEY_READ,
  566. &hKey) != NOERROR)
  567. {
  568. // The folder does not exist
  569. //
  570. g_uResponseTimeout = ILS_MIN_RESP_TIMEOUT;
  571. g_uResponsePollPeriod = ILS_DEF_RESP_POLL_PERIOD;
  572. g_dwClientSig = (ULONG) -1;
  573. }
  574. else
  575. {
  576. // Get response timeout
  577. //
  578. GetRegValueLong ( hKey,
  579. &c_szResponseTimeout[0],
  580. (LONG *) &g_uResponseTimeout,
  581. ILS_DEF_RESP_TIMEOUT);
  582. // Make sure the value is within the range
  583. //
  584. if (g_uResponseTimeout < ILS_MIN_RESP_TIMEOUT)
  585. g_uResponseTimeout = ILS_MIN_RESP_TIMEOUT;
  586. // Get response poll period
  587. //
  588. GetRegValueLong ( hKey,
  589. &c_szResponsePollPeriod[0],
  590. (LONG *) &g_uResponsePollPeriod,
  591. ILS_DEF_RESP_POLL_PERIOD);
  592. // Make sure the value is within the range
  593. //
  594. if (g_uResponsePollPeriod < ILS_MIN_RESP_POLL_PERIOD)
  595. g_uResponsePollPeriod = ILS_MIN_RESP_POLL_PERIOD;
  596. // Get client signature
  597. //
  598. GetRegValueLong ( hKey,
  599. &c_szClientSig[0],
  600. (LONG *) &g_dwClientSig,
  601. (LONG) -1);
  602. RegCloseKey (hKey);
  603. }
  604. // Make sure this value is not -1
  605. //
  606. if (g_dwClientSig == (ULONG) -1)
  607. {
  608. // The client signature does not exist.
  609. // We need to generate a new one
  610. //
  611. g_dwClientSig = GetTickCount ();
  612. // Save it back to the registry
  613. //
  614. DWORD dwDontCare;
  615. if (RegCreateKeyEx (HKEY_CURRENT_USER,
  616. &c_szUlsLdapSpReg[0],
  617. 0,
  618. TEXT (""),
  619. REG_OPTION_NON_VOLATILE,
  620. KEY_READ | KEY_WRITE,
  621. NULL,
  622. &hKey,
  623. &dwDontCare) == NOERROR)
  624. {
  625. RegSetValueEx ( hKey,
  626. &c_szClientSig[0],
  627. 0,
  628. REG_DWORD,
  629. (BYTE *) &g_dwClientSig,
  630. sizeof (&g_dwClientSig));
  631. }
  632. }
  633. return TRUE;
  634. }
  635. BOOL
  636. GetRegValueLong (
  637. HKEY hKey,
  638. const TCHAR *pszKey,
  639. LONG *plValue,
  640. LONG lDefValue )
  641. {
  642. MyAssert (hKey != NULL);
  643. MyAssert (pszKey != NULL);
  644. MyAssert (plValue != NULL);
  645. *plValue = lDefValue;
  646. DWORD dwType;
  647. ULONG cb;
  648. TCHAR szText[MAX_PATH];
  649. cb = sizeof (szText);
  650. if (RegQueryValueEx ( hKey,
  651. pszKey,
  652. NULL,
  653. &dwType,
  654. (BYTE *) &szText[0],
  655. &cb)
  656. == ERROR_SUCCESS)
  657. {
  658. switch (dwType)
  659. {
  660. case REG_DWORD:
  661. case REG_BINARY:
  662. *plValue = *(LONG *) &szText[0];
  663. break;
  664. case REG_SZ:
  665. *plValue = GetStringLong (&szText[0]);
  666. break;
  667. default:
  668. return FALSE;
  669. }
  670. }
  671. return TRUE;
  672. }
  673. /* ------- LDAP error codes ---------- */
  674. const LONG c_LdapErrToHrShort[] =
  675. {
  676. // End of search (per AndyHe info)
  677. LDAP_PARAM_ERROR, ILS_E_PARAMETER,
  678. // Keep alive fails
  679. LDAP_NO_SUCH_OBJECT, ILS_E_NO_SUCH_OBJECT,
  680. // Logon with conflicting email name
  681. LDAP_ALREADY_EXISTS, ILS_E_NAME_CONFLICTS,
  682. LDAP_OPERATIONS_ERROR, ILS_E_LDAP_OPERATIONS_ERROR,
  683. LDAP_PROTOCOL_ERROR, ILS_E_LDAP_PROTOCOL_ERROR,
  684. LDAP_TIMELIMIT_EXCEEDED, ILS_E_LDAP_TIMELIMIT_EXCEEDED,
  685. LDAP_SIZELIMIT_EXCEEDED, ILS_E_LDAP_SIZELIMIT_EXCEEDED,
  686. LDAP_COMPARE_FALSE, ILS_E_LDAP_COMPARE_FALSE,
  687. LDAP_COMPARE_TRUE, ILS_E_LDAP_COMPARE_TRUE,
  688. LDAP_AUTH_METHOD_NOT_SUPPORTED, ILS_E_LDAP_AUTH_METHOD_NOT_SUPPORTED,
  689. LDAP_STRONG_AUTH_REQUIRED, ILS_E_LDAP_STRONG_AUTH_REQUIRED,
  690. LDAP_REFERRAL_V2, ILS_E_LDAP_REFERRAL_V2,
  691. LDAP_PARTIAL_RESULTS, ILS_E_LDAP_PARTIAL_RESULTS,
  692. LDAP_REFERRAL, ILS_E_LDAP_REFERRAL,
  693. LDAP_ADMIN_LIMIT_EXCEEDED, ILS_E_LDAP_ADMIN_LIMIT_EXCEEDED,
  694. LDAP_UNAVAILABLE_CRIT_EXTENSION,ILS_E_LDAP_UNAVAILABLE_CRIT_EXTENSION,
  695. LDAP_NO_SUCH_ATTRIBUTE, ILS_E_LDAP_NO_SUCH_ATTRIBUTE,
  696. LDAP_UNDEFINED_TYPE, ILS_E_LDAP_UNDEFINED_TYPE,
  697. LDAP_INAPPROPRIATE_MATCHING, ILS_E_LDAP_INAPPROPRIATE_MATCHING,
  698. LDAP_CONSTRAINT_VIOLATION, ILS_E_LDAP_CONSTRAINT_VIOLATION,
  699. LDAP_ATTRIBUTE_OR_VALUE_EXISTS, ILS_E_LDAP_ATTRIBUTE_OR_VALUE_EXISTS,
  700. LDAP_INVALID_SYNTAX, ILS_E_LDAP_INVALID_SYNTAX,
  701. LDAP_ALIAS_PROBLEM, ILS_E_LDAP_ALIAS_PROBLEM,
  702. LDAP_INVALID_DN_SYNTAX, ILS_E_LDAP_INVALID_DN_SYNTAX,
  703. LDAP_IS_LEAF, ILS_E_LDAP_IS_LEAF,
  704. LDAP_ALIAS_DEREF_PROBLEM, ILS_E_LDAP_ALIAS_DEREF_PROBLEM,
  705. LDAP_INAPPROPRIATE_AUTH, ILS_E_LDAP_INAPPROPRIATE_AUTH,
  706. LDAP_INVALID_CREDENTIALS, ILS_E_LDAP_INVALID_CREDENTIALS,
  707. LDAP_INSUFFICIENT_RIGHTS, ILS_E_LDAP_INSUFFICIENT_RIGHTS,
  708. LDAP_BUSY, ILS_E_LDAP_BUSY,
  709. LDAP_UNAVAILABLE, ILS_E_LDAP_UNAVAILABLE,
  710. LDAP_UNWILLING_TO_PERFORM, ILS_E_LDAP_UNWILLING_TO_PERFORM,
  711. LDAP_LOOP_DETECT, ILS_E_LDAP_LOOP_DETECT,
  712. LDAP_NAMING_VIOLATION, ILS_E_LDAP_NAMING_VIOLATION,
  713. LDAP_OBJECT_CLASS_VIOLATION, ILS_E_LDAP_OBJECT_CLASS_VIOLATION,
  714. LDAP_NOT_ALLOWED_ON_NONLEAF, ILS_E_LDAP_NOT_ALLOWED_ON_NONLEAF,
  715. LDAP_NOT_ALLOWED_ON_RDN, ILS_E_LDAP_NOT_ALLOWED_ON_RDN,
  716. LDAP_NO_OBJECT_CLASS_MODS, ILS_E_LDAP_NO_OBJECT_CLASS_MODS,
  717. LDAP_RESULTS_TOO_LARGE, ILS_E_LDAP_RESULTS_TOO_LARGE,
  718. LDAP_AFFECTS_MULTIPLE_DSAS, ILS_E_LDAP_AFFECTS_MULTIPLE_DSAS,
  719. LDAP_OTHER, ILS_E_LDAP_OTHER,
  720. LDAP_SERVER_DOWN, ILS_E_LDAP_SERVER_DOWN,
  721. LDAP_LOCAL_ERROR, ILS_E_LDAP_LOCAL_ERROR,
  722. LDAP_ENCODING_ERROR, ILS_E_LDAP_ENCODING_ERROR,
  723. LDAP_DECODING_ERROR, ILS_E_LDAP_DECODING_ERROR,
  724. LDAP_TIMEOUT, ILS_E_LDAP_TIMEOUT,
  725. LDAP_AUTH_UNKNOWN, ILS_E_LDAP_AUTH_UNKNOWN,
  726. LDAP_FILTER_ERROR, ILS_E_LDAP_FILTER_ERROR,
  727. LDAP_USER_CANCELLED, ILS_E_LDAP_USER_CANCELLED,
  728. LDAP_NO_MEMORY, ILS_E_LDAP_NO_MEMORY,
  729. };
  730. HRESULT
  731. LdapError2Hresult ( ULONG uLdapError )
  732. {
  733. HRESULT hr;
  734. switch (uLdapError)
  735. {
  736. case LDAP_SUCCESS:
  737. hr = S_OK;
  738. break;
  739. default:
  740. // If nothing appears to be appropriate
  741. //
  742. hr = ILS_E_SERVER_EXEC;
  743. // Go through the loop to find a matching error code
  744. //
  745. for ( INT i = 0;
  746. i < ARRAY_ELEMENTS (c_LdapErrToHrShort);
  747. i += 2)
  748. {
  749. if (c_LdapErrToHrShort[i] == (LONG) uLdapError)
  750. {
  751. hr = (HRESULT) c_LdapErrToHrShort[i+1];
  752. break;
  753. }
  754. }
  755. MyAssert (hr != ILS_E_SERVER_EXEC);
  756. break;
  757. }
  758. return hr;
  759. }