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.

1819 lines
44 KiB

  1. /*--
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. kerbtray.c
  5. Abstract:
  6. Displays a dialog with list of Kerberos tickets for the current user.
  7. Author:
  8. 14-Dec-1998 (jbrezak)
  9. Environment:
  10. User mode only.
  11. Requires ANSI C extensions: slash-slash comments, long external names.
  12. Revision History:
  13. --*/
  14. #define UNICODE
  15. #define _UNICODE
  16. #define STRICT
  17. #include <windows.h>
  18. #include <stdarg.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <shellapi.h>
  22. #include <shlwapi.h>
  23. #include <commctrl.h>
  24. #include <commdlg.h>
  25. #include <time.h>
  26. #include <assert.h>
  27. #include <string.h>
  28. #include <malloc.h>
  29. #define SECURITY_WIN32
  30. #include <security.h>
  31. #include <ntsecapi.h>
  32. #ifndef NO_CRYPTDLL
  33. #include "cryptdll.h"
  34. #endif
  35. #include "kerbtray.h"
  36. #define SEC_SUCCESS(Status) ((Status) >= 0)
  37. #define TSIZE(b) (sizeof(b)/sizeof(TCHAR))
  38. #define IDI_FIRST_CLOCK IDI_0_MIN
  39. #define IDI_LAST_CLOCK IDI_TICKET
  40. #define MAX_ICONS (IDI_LAST_CLOCK - IDI_FIRST_CLOCK + 1)
  41. #define KWIN_UPDATE_PERIOD 60000 // Every 60 seconds update the screen
  42. #define PPAGE_NAMES 0
  43. #define PPAGE_TIMES 1
  44. #define PPAGE_FLAGS 2
  45. #define PPAGE_ETYPES 3
  46. #define C_PAGES 4
  47. #define CX_ICON 20
  48. #define CY_ICON 20
  49. #define TPS (10*1000*1000)
  50. typedef struct
  51. {
  52. HWND hwndTab;
  53. HWND hwndDisplay;
  54. RECT rcDisplay;
  55. DLGTEMPLATE *apRes[C_PAGES];
  56. PKERB_QUERY_TKT_CACHE_RESPONSE Tickets;
  57. } DLGTABHDR;
  58. OSVERSIONINFO osvers;
  59. HWND hWnd, hDlgTickets;
  60. HINSTANCE hInstance;
  61. HANDLE hModule;
  62. #define SHORTSTRING 40
  63. #define LONGSTRING 256
  64. TCHAR progname[SHORTSTRING];
  65. ULONG PackageId;
  66. HANDLE LogonHandle = NULL;
  67. HWND hWndUsers;
  68. HIMAGELIST himl;
  69. HTREEITEM tgt = NULL;
  70. static HICON kwin_icons[MAX_ICONS]; // Icons depicting time
  71. static INT domain_icon;
  72. static LPCTSTR dt_output_dhms = TEXT("%d %s %02d:%02d:%02d");
  73. static LPCTSTR dt_day_plural = TEXT("days");
  74. static LPCTSTR dt_day_singular = TEXT("day");
  75. static LPCTSTR dt_output_donly = TEXT("%d %s");
  76. static LPCTSTR dt_output_hms = TEXT("%d:%02d:%02d");
  77. static LPCTSTR ftime_default_fmt = TEXT("%02d/%02d/%02d %02d:%02d");
  78. #define WM_NOTIFY_ICON (WM_APP+100)
  79. #ifndef NO_CRYPTDLL
  80. typedef NTSTATUS (NTAPI *CDLOCATECSYSTEM)(ULONG dwEtype, PCRYPTO_SYSTEM * ppcsSystem);
  81. CDLOCATECSYSTEM pCDLocateCSystem;
  82. #endif
  83. LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
  84. LRESULT CALLBACK AboutProc(HWND, UINT, WPARAM, LPARAM);
  85. LRESULT CALLBACK TicketsProc(HWND, UINT, WPARAM, LPARAM);
  86. void About(void);
  87. void Tickets(void);
  88. void PurgeCache(void);
  89. void PropsheetDisplay(HWND hDlg);
  90. void SelectTicket(HWND hDlg);
  91. void FillinTicket(HWND hDlg);
  92. LPTSTR etype_string(int enctype);
  93. LPTSTR GetStringRes(int);
  94. #ifdef DEBUG
  95. #define DPRINTF(s) dprintf s
  96. int debug = 1;
  97. void dprintf(LPCTSTR fmt, ...)
  98. {
  99. TCHAR szTemp[512];
  100. va_list ap;
  101. if (!debug)
  102. return;
  103. va_start (ap, fmt);
  104. wvsprintf(szTemp, fmt, ap);
  105. OutputDebugString(szTemp);
  106. va_end (ap);
  107. }
  108. #else
  109. #define DPRINTF(s)
  110. #endif
  111. void
  112. ShowMessage(int level, LPCTSTR msg)
  113. /*++
  114. Routine Description:
  115. Arguments:
  116. Return Value:
  117. --*/
  118. {
  119. if (level)
  120. MessageBeep(level);
  121. MessageBox(NULL, msg, progname,
  122. level | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
  123. }
  124. void
  125. Error(LPCTSTR fmt, ...)
  126. /*++
  127. Routine Description:
  128. Arguments:
  129. Return Value:
  130. --*/
  131. {
  132. TCHAR szTemp[512];
  133. va_list ap;
  134. va_start (ap, fmt);
  135. #ifdef UNICODE
  136. _vsnwprintf(szTemp, sizeof(szTemp), fmt, ap);
  137. #else
  138. _vsnprintf(szTemp, sizeof(szTemp), fmt, ap);
  139. #endif
  140. OutputDebugString(szTemp);
  141. ShowMessage(MB_ICONINFORMATION, szTemp);
  142. va_end (ap);
  143. }
  144. void
  145. ErrorExit(LPCTSTR lpszMessage)
  146. /*++
  147. Routine Description:
  148. Arguments:
  149. Return Value:
  150. --*/
  151. {
  152. MessageBox(hWnd, lpszMessage, TEXT("Error"), MB_OK);
  153. ExitProcess(0);
  154. }
  155. int
  156. GetIconIndex(long dt)
  157. /*++
  158. Routine Description:
  159. Arguments:
  160. Return Value:
  161. --*/
  162. {
  163. int ixicon;
  164. dt = dt / 60; // convert to minutes
  165. if (dt <= 0)
  166. ixicon = IDI_EXPIRED - IDI_FIRST_CLOCK;
  167. else if (dt > 60)
  168. ixicon = IDI_TICKET - IDI_FIRST_CLOCK;
  169. else
  170. ixicon = (int)(dt / 5);
  171. return ixicon;
  172. }
  173. void
  174. SetTray(
  175. HWND hwnd,
  176. HICON hIcon,
  177. LPCTSTR tip
  178. )
  179. /*++
  180. Routine Description:
  181. Arguments:
  182. Return Value:
  183. --*/
  184. {
  185. static tray_inited = 0;
  186. NOTIFYICONDATA tnd;
  187. tnd.cbSize = sizeof(NOTIFYICONDATA);
  188. tnd.hWnd = hwnd;
  189. tnd.uID = IDI_KDC;
  190. tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
  191. tnd.uCallbackMessage = WM_NOTIFY_ICON;
  192. tnd.hIcon = hIcon;
  193. StrNCpy(tnd.szTip, tip, TSIZE(tnd.szTip));
  194. Shell_NotifyIcon((tray_inited)?NIM_MODIFY:NIM_ADD, &tnd);
  195. if (tray_inited == 0)
  196. tray_inited++;
  197. DestroyIcon(tnd.hIcon);
  198. }
  199. void
  200. DeleteTray(HWND hwnd)
  201. /*++
  202. Routine Description:
  203. Arguments:
  204. Return Value:
  205. --*/
  206. {
  207. NOTIFYICONDATA tnd;
  208. tnd.cbSize = sizeof(NOTIFYICONDATA);
  209. tnd.hWnd = hwnd;
  210. tnd.uID = IDI_KDC;
  211. tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
  212. tnd.uCallbackMessage = WM_NOTIFY_ICON;
  213. tnd.hIcon = NULL;
  214. tnd.szTip[0] = '\0';
  215. Shell_NotifyIcon(NIM_DELETE, &tnd);
  216. }
  217. int
  218. UpdateTray(HWND hwnd)
  219. /*++
  220. Routine Description:
  221. Arguments:
  222. Return Value:
  223. --*/
  224. {
  225. HICON hicon;
  226. TCHAR buf[SHORTSTRING];
  227. int expired = FALSE;
  228. long dt = 0L;
  229. NTSTATUS Status, SubStatus;
  230. KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
  231. PKERB_RETRIEVE_TKT_RESPONSE TicketEntry = NULL;
  232. PKERB_EXTERNAL_TICKET Ticket;
  233. ULONG ResponseSize;
  234. FILETIME CurrentFileTime;
  235. LARGE_INTEGER Quad;
  236. CacheRequest.MessageType = KerbRetrieveTicketMessage;
  237. CacheRequest.LogonId.LowPart = 0;
  238. CacheRequest.LogonId.HighPart = 0;
  239. StrNCpy(buf, progname, TSIZE(buf));
  240. Status = LsaCallAuthenticationPackage(LogonHandle,
  241. PackageId,
  242. &CacheRequest,
  243. sizeof(CacheRequest),
  244. (PVOID *) &TicketEntry,
  245. &ResponseSize,
  246. &SubStatus);
  247. if (!SEC_SUCCESS(Status) || !SEC_SUCCESS(SubStatus)) {
  248. hicon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_KDC));
  249. StrCatBuff(buf, GetStringRes(IDS_NO_CREDS), TSIZE(buf));
  250. }
  251. else {
  252. Ticket = &(TicketEntry->Ticket);
  253. GetSystemTimeAsFileTime(&CurrentFileTime);
  254. Quad.LowPart = CurrentFileTime.dwLowDateTime;
  255. Quad.HighPart = CurrentFileTime.dwHighDateTime;
  256. dt = (long)((Ticket->EndTime.QuadPart - Quad.QuadPart) / TPS);
  257. LsaFreeReturnBuffer(TicketEntry);
  258. hicon = kwin_icons[GetIconIndex(dt)];
  259. StrCatBuff(buf, TEXT(" - "), TSIZE(buf));
  260. if (dt <= 0) {
  261. StrCatBuff(buf, GetStringRes(IDS_EXPIRED), TSIZE(buf));
  262. expired = TRUE;
  263. }
  264. else {
  265. int days, hours, minutes, seconds;
  266. DWORD tt;
  267. TCHAR buf2[SHORTSTRING];
  268. days = (int) (dt / (24*3600l));
  269. tt = dt % (24*3600l);
  270. hours = (int) (tt / 3600);
  271. tt %= 3600;
  272. minutes = (int) (tt / 60);
  273. seconds = (int) (tt % 60);
  274. if (days) {
  275. if (hours || minutes || seconds) {
  276. _snwprintf(buf2, TSIZE(buf2), dt_output_dhms, days,
  277. (days > 1) ? dt_day_plural : dt_day_singular,
  278. hours, minutes, seconds);
  279. }
  280. else {
  281. _snwprintf(buf2, TSIZE(buf2), dt_output_donly, days,
  282. (days > 1) ? dt_day_plural : dt_day_singular);
  283. }
  284. }
  285. else {
  286. _snwprintf(buf2, TSIZE(buf2), dt_output_hms,
  287. hours, minutes, seconds);
  288. }
  289. _snwprintf(buf, TSIZE(buf), TEXT("%s %s"), progname, buf2);
  290. }
  291. }
  292. SetTray(hwnd, hicon, buf);
  293. return(expired);
  294. }
  295. BOOL
  296. InitializeApp(
  297. HANDLE hInstance,
  298. int nCmdShow
  299. )
  300. /*++
  301. Routine Description:
  302. Arguments:
  303. Return Value:
  304. --*/
  305. {
  306. LSA_STRING Name;
  307. NTSTATUS Status;
  308. WNDCLASSEX wc;
  309. HWND hwnd;
  310. int i;
  311. // Check for an existing instance
  312. hwnd = FindWindow(TEXT("MainWindowClass"), TEXT("KerbTray"));
  313. if (hwnd) {
  314. // Popup the tickets dialog, if one found
  315. // Run only one instance of kerbtray
  316. SendMessage(hwnd, WM_NOTIFY_ICON, 0, WM_LBUTTONDBLCLK);
  317. ExitProcess(0);
  318. }
  319. hModule = GetModuleHandle(NULL);
  320. InitCommonControls();
  321. LoadString(hInstance, IDS_KRB5_NAME, progname, TSIZE(progname));
  322. Status = LsaConnectUntrusted(&LogonHandle);
  323. if (!SEC_SUCCESS(Status)) {
  324. Error(TEXT("Failed to register as a logon process: 0x%x"), Status);
  325. return FALSE;
  326. }
  327. Name.Buffer = MICROSOFT_KERBEROS_NAME_A;
  328. Name.Length = (USHORT) strlen(Name.Buffer);
  329. Name.MaximumLength = Name.Length + 1;
  330. Status = LsaLookupAuthenticationPackage(
  331. LogonHandle,
  332. &Name,
  333. &PackageId
  334. );
  335. if (!SEC_SUCCESS(Status)){
  336. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  337. return FALSE;
  338. }
  339. // Create the image list.
  340. if ((himl = ImageList_Create(CX_ICON, CY_ICON, ILC_COLOR, MAX_ICONS, 0)) == NULL)
  341. return FALSE;
  342. ImageList_SetBkColor(himl, CLR_NONE);
  343. for (i = IDI_FIRST_CLOCK; i <= IDI_LAST_CLOCK; i++) {
  344. #if 1
  345. kwin_icons[i - IDI_FIRST_CLOCK] = LoadIcon(hInstance,
  346. MAKEINTRESOURCE(i));
  347. #else
  348. kwin_icons[i - IDI_FIRST_CLOCK] = LoadImage(hInstance,
  349. MAKEINTRESOURCE(i),
  350. IMAGE_ICON, 0, 0,
  351. LR_DEFAULTCOLOR|LR_DEFAULTSIZE|LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS);
  352. #endif
  353. (void) ImageList_AddIcon(himl, kwin_icons[i - IDI_FIRST_CLOCK]);
  354. }
  355. #if 1
  356. domain_icon = ImageList_AddIcon(himl,
  357. LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DOMAIN)));
  358. #else
  359. domain_icon = ImageList_AddIcon(himl,
  360. LoadImage(hInstance, MAKEINTRESOURCE(IDI_DOMAIN),
  361. IMAGE_ICON, 0, 0,
  362. LR_DEFAULTCOLOR|LR_DEFAULTSIZE|LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS));
  363. #endif
  364. // Register a window class for the main window.
  365. wc.cbSize = sizeof(WNDCLASSEX);
  366. wc.style = CS_HREDRAW|CS_VREDRAW;
  367. wc.lpfnWndProc = MainWndProc;
  368. wc.cbClsExtra = 0;
  369. wc.cbWndExtra = 0;
  370. wc.hInstance = hInstance;
  371. wc.hIcon = LoadIcon(hModule, MAKEINTRESOURCE(IDI_EXPIRED));
  372. wc.hIconSm = LoadIcon(hModule, MAKEINTRESOURCE(IDI_EXPIRED));
  373. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  374. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  375. wc.lpszMenuName = 0;
  376. wc.lpszClassName = TEXT("MainWindowClass");
  377. if (! RegisterClassEx(&wc)) {
  378. Error(TEXT("RegisterClassEx failed"));
  379. return FALSE;
  380. }
  381. /* Create the main window. */
  382. hWnd = CreateWindowEx(WS_EX_APPWINDOW,
  383. TEXT("MainWindowClass"),
  384. TEXT("KerbTray"),
  385. WS_OVERLAPPEDWINDOW,
  386. 0, 0,
  387. 5, 5,
  388. NULL,
  389. NULL,
  390. hModule,
  391. NULL);
  392. if (hWnd == NULL) {
  393. Error(TEXT("CreateWindowEx failed"));
  394. return FALSE;
  395. }
  396. ShowWindow(hWnd, SW_HIDE);
  397. return TRUE;
  398. }
  399. int WINAPI
  400. WinMain(
  401. HINSTANCE hInst,
  402. HINSTANCE hPrevInst,
  403. LPSTR lpszCmdLn,
  404. int nShowCmd
  405. )
  406. /*++
  407. Routine Description:
  408. Arguments:
  409. Return Value:
  410. --*/
  411. {
  412. MSG msg;
  413. HANDLE hAccelTable, hCryptDll;
  414. hInstance = hInst;
  415. hModule = GetModuleHandle(NULL);
  416. osvers.dwOSVersionInfoSize = sizeof(osvers);
  417. GetVersionEx(&osvers);
  418. #ifndef NO_CRYPTDLL
  419. hCryptDll = LoadLibrary(TEXT("CRYPTDLL.DLL"));
  420. if (!hCryptDll)
  421. ErrorExit(TEXT("Unable to load cryptdll.dll"));
  422. pCDLocateCSystem = (CDLOCATECSYSTEM) GetProcAddress(hCryptDll, "CDLocateCSystem");
  423. if (!pCDLocateCSystem)
  424. ErrorExit(TEXT("Unable to link cryptdll.dll::CDLocateCSystem"));
  425. #endif
  426. if (! InitializeApp(hInst, nShowCmd))
  427. ErrorExit(TEXT("InitializeApp failure"));
  428. hAccelTable = LoadAccelerators(hInst, TEXT("KerbTray"));
  429. while (GetMessage(&msg, NULL, 0, 0)) {
  430. if (!IsDialogMessage(hDlgTickets, &msg)) {
  431. if (!TranslateAccelerator (msg.hwnd, hAccelTable, &msg)) {
  432. TranslateMessage(&msg);
  433. DispatchMessage(&msg);
  434. }
  435. }
  436. }
  437. return 1;
  438. UNREFERENCED_PARAMETER(hPrevInst);
  439. UNREFERENCED_PARAMETER(lpszCmdLn);
  440. }
  441. LRESULT CALLBACK
  442. MainWndProc(HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
  443. /*++
  444. Routine Description:
  445. Arguments:
  446. Return Value:
  447. --*/
  448. {
  449. POINT pos;
  450. static HMENU hPopupMenu;
  451. switch (uiMessage) {
  452. case WM_NOTIFY_ICON:
  453. switch (lParam) {
  454. case WM_LBUTTONDBLCLK:
  455. Tickets();
  456. return 0L;
  457. case WM_RBUTTONDOWN:
  458. if (hPopupMenu) {
  459. if (GetCursorPos(&pos)) {
  460. if (TrackPopupMenu(hPopupMenu,
  461. TPM_RIGHTALIGN|TPM_LEFTBUTTON,
  462. pos.x, pos.y,
  463. 0, hwnd, NULL) == 0)
  464. Error(TEXT("TrackPopupMenuFailed: 0x%x"),
  465. GetLastError());
  466. }
  467. }
  468. return 0L;
  469. }
  470. break;
  471. /* Create a client windows */
  472. case WM_CREATE:
  473. hPopupMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU));
  474. if (!hPopupMenu)
  475. Error(TEXT("LoadMenu failed %d"), GetLastError());
  476. hPopupMenu = GetSubMenu(hPopupMenu, 0);
  477. if (!hPopupMenu)
  478. Error(TEXT("LoadMenu failed %d"), GetLastError());
  479. (void) UpdateTray(hwnd);
  480. /* Start timer for watching the TGT */
  481. if (!SetTimer(hwnd, 1, KWIN_UPDATE_PERIOD, NULL)) {
  482. ErrorExit(TEXT("SetTimer failed"));
  483. }
  484. return 0L;
  485. case WM_TIMER:
  486. (void) UpdateTray(hwnd);
  487. return(0L);
  488. case WM_ENDSESSION:
  489. return(0L);
  490. /*
  491. * Close the main window. First set fKillAll to TRUE to
  492. * terminate all threads. Then wait for the threads to exit
  493. * before passing a close message to a default handler. If you
  494. * don't wait for threads to terminate, process terminates
  495. * with no chance for thread cleanup.
  496. */
  497. case WM_CLOSE:
  498. exit:;
  499. {
  500. DeleteTray(hWnd);
  501. KillTimer(hWnd, 1);
  502. PostQuitMessage(0);
  503. return 0L;
  504. }
  505. /* Terminate the process. */
  506. case WM_DESTROY:
  507. PostQuitMessage(0);
  508. return 0L;
  509. /* Handle the menu commands. */
  510. case WM_COMMAND:
  511. switch (LOWORD(wParam)) {
  512. case ID_ABOUT:
  513. About();
  514. return 0L;
  515. case ID_TICKETS:
  516. Tickets();
  517. return 0L;
  518. case ID_PURGE:
  519. PurgeCache();
  520. return 0L;
  521. case ID_EXIT:
  522. goto exit;
  523. }
  524. }
  525. return DefWindowProc(hwnd, uiMessage, wParam, lParam);
  526. }
  527. LPTSTR
  528. GetStringRes(int id)
  529. /*++
  530. Routine Description:
  531. Arguments:
  532. Return Value:
  533. --*/
  534. {
  535. static TCHAR buffer[MAX_PATH];
  536. buffer[0] = 0;
  537. LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH);
  538. return buffer;
  539. }
  540. LRESULT CALLBACK
  541. AboutProc(
  542. HWND hDlg,
  543. UINT message,
  544. WPARAM wParam,
  545. LPARAM lParam
  546. )
  547. /*++
  548. Routine Description:
  549. Arguments:
  550. Return Value:
  551. --*/
  552. {
  553. static HFONT hfontDlg; // Font for dialog text
  554. DWORD dwVerInfoSize; // Size of version information block
  555. LPTSTR lpVersion; // String pointer to 'version' text
  556. DWORD dwVerHnd = 0; // An 'ignored' parameter, always '0'
  557. UINT uVersionLen;
  558. DWORD wRootLen;
  559. BOOL bRetCode;
  560. int i;
  561. TCHAR szFullPath[LONGSTRING];
  562. TCHAR szResult[LONGSTRING];
  563. TCHAR szGetName[LONGSTRING];
  564. TCHAR szVersion[SHORTSTRING];
  565. DWORD dwResult;
  566. int resmap[6] = {
  567. IDC_COMPANY,
  568. IDC_FILEDESC,
  569. IDC_PRODVER,
  570. IDC_COPYRIGHT,
  571. IDC_OSVERSION,
  572. };
  573. switch (message) {
  574. case WM_INITDIALOG:
  575. ShowWindow(hDlg, SW_HIDE);
  576. hfontDlg = CreateFont(14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  577. VARIABLE_PITCH | FF_SWISS, TEXT(""));
  578. GetModuleFileName(hInstance, szFullPath, TSIZE(szFullPath));
  579. /* Now lets dive in and pull out the version information: */
  580. dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd);
  581. if (dwVerInfoSize) {
  582. LPSTR lpstrVffInfo;
  583. HANDLE hMem;
  584. hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  585. if (!hMem) {
  586. ErrorExit(TEXT("Unable to allocate memory"));
  587. }
  588. lpstrVffInfo = GlobalLock(hMem);
  589. if (!lpstrVffInfo) {
  590. ErrorExit(TEXT("Unable to lock memory"));
  591. }
  592. GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, lpstrVffInfo);
  593. /*
  594. * The below 'hex' value looks a little confusing, but
  595. * essentially what it is, is the hexidecimal representation
  596. * of a couple different values that represent the language
  597. * and character set that we are wanting string values for.
  598. * 040904E4 is a very common one, because it means:
  599. * US English, Windows MultiLingual characterset
  600. * Or to pull it all apart:
  601. * 04------ = SUBLANG_ENGLISH_USA
  602. * --09---- = LANG_ENGLISH
  603. * ----04E4 = 1252 = Codepage for Windows:Multilingual
  604. */
  605. StrNCpy(szGetName, GetStringRes(IDS_VER_INFO_LANG), TSIZE(szGetName));
  606. wRootLen = lstrlen(szGetName); /* Save this position */
  607. /* Set the title of the dialog: */
  608. StrCatBuff(szGetName, TEXT("ProductName"), TSIZE(szGetName));
  609. bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
  610. (LPTSTR)szGetName,
  611. (LPVOID)&lpVersion,
  612. (UINT *)&uVersionLen);
  613. StrNCpy(szResult, TEXT("About "), TSIZE(szResult));
  614. StrCatBuff(szResult, lpVersion, TSIZE(szResult));
  615. SetWindowText(hDlg, szResult);
  616. /* Walk through the dialog items that we want to replace: */
  617. for (i = 0; i <= 6; i++) {
  618. GetDlgItemText(hDlg, resmap[i], szResult, TSIZE(szResult));
  619. szGetName[wRootLen] = TEXT('\0');
  620. StrCatBuff(szGetName, szResult, TSIZE(szGetName));
  621. uVersionLen = 0;
  622. lpVersion = NULL;
  623. bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
  624. (LPTSTR)szGetName,
  625. (LPVOID)&lpVersion,
  626. (UINT *)&uVersionLen);
  627. if ( bRetCode && uVersionLen && lpVersion) {
  628. /* Replace dialog item text with version info */
  629. StrNCpy(szResult, lpVersion, TSIZE(szResult));
  630. SetDlgItemText(hDlg, resmap[i], szResult);
  631. } else {
  632. dwResult = GetLastError();
  633. _snwprintf(szResult, TSIZE(szResult),
  634. TEXT("Error %lu"), dwResult);
  635. SetDlgItemText (hDlg, resmap[i], szResult);
  636. }
  637. SendMessage(GetDlgItem(hDlg, resmap[i]), WM_SETFONT,
  638. (WPARAM)hfontDlg,
  639. TRUE);
  640. }
  641. GlobalUnlock(hMem);
  642. GlobalFree(hMem);
  643. } else {
  644. /* No version information available. */
  645. }
  646. SendMessage(GetDlgItem (hDlg, IDC_LABEL), WM_SETFONT,
  647. (WPARAM)hfontDlg,(LPARAM)TRUE);
  648. _snwprintf(szVersion, TSIZE(szVersion),
  649. TEXT("Microsoft Windows %u.%u (Build: %u)"),
  650. osvers.dwMajorVersion,
  651. osvers.dwMinorVersion,
  652. osvers.dwBuildNumber);
  653. SetWindowText(GetDlgItem(hDlg, IDC_OSVERSION), szVersion);
  654. ShowWindow(hDlg, SW_SHOW);
  655. return TRUE;
  656. case WM_COMMAND:
  657. switch (LOWORD(wParam)) {
  658. case IDOK:
  659. case IDCANCEL:
  660. EndDialog(hDlg, 0);
  661. break;
  662. }
  663. }
  664. return FALSE;
  665. }
  666. void
  667. About(void)
  668. /*++
  669. Routine Description:
  670. Arguments:
  671. Return Value:
  672. --*/
  673. {
  674. DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hWnd, AboutProc);
  675. }
  676. #define CheckDlgButtonFlag(b, f) \
  677. CheckDlgButton(hDlg, b, (flags & f)?BST_CHECKED:BST_UNCHECKED)
  678. VOID
  679. ShowFlags(HWND hDlg, ULONG flags)
  680. /*++
  681. Routine Description:
  682. Arguments:
  683. Return Value:
  684. --*/
  685. {
  686. CheckDlgButtonFlag(IDC_FORWARDABLE, KERB_TICKET_FLAGS_forwardable);
  687. CheckDlgButtonFlag(IDC_FORWARDED, KERB_TICKET_FLAGS_forwarded);
  688. CheckDlgButtonFlag(IDC_PROXIABLE, KERB_TICKET_FLAGS_proxiable);
  689. CheckDlgButtonFlag(IDC_PROXY, KERB_TICKET_FLAGS_proxy);
  690. CheckDlgButtonFlag(IDC_MAY_POSTDATE, KERB_TICKET_FLAGS_may_postdate);
  691. CheckDlgButtonFlag(IDC_POSTDATED, KERB_TICKET_FLAGS_postdated);
  692. CheckDlgButtonFlag(IDC_INVALID, KERB_TICKET_FLAGS_invalid);
  693. CheckDlgButtonFlag(IDC_RENEWABLE, KERB_TICKET_FLAGS_renewable);
  694. CheckDlgButtonFlag(IDC_INITIAL, KERB_TICKET_FLAGS_initial);
  695. CheckDlgButtonFlag(IDC_HWAUTH, KERB_TICKET_FLAGS_hw_authent);
  696. CheckDlgButtonFlag(IDC_PREAUTH, KERB_TICKET_FLAGS_pre_authent);
  697. CheckDlgButtonFlag(IDC_OK_AS_DELEGATE, KERB_TICKET_FLAGS_ok_as_delegate);
  698. }
  699. LPTSTR
  700. etype_string(
  701. int enctype
  702. )
  703. /*++
  704. Routine Description:
  705. Arguments:
  706. Return Value:
  707. --*/
  708. {
  709. #ifndef NO_CRYPTDLL
  710. static PCRYPTO_SYSTEM pcsSystem;
  711. static TCHAR buf[12];
  712. if (pCDLocateCSystem(enctype, &pcsSystem) == S_OK)
  713. return pcsSystem->Name;
  714. else {
  715. _snwprintf(buf, TSIZE(buf), TEXT("etype %d"), enctype);
  716. return buf;
  717. }
  718. #else
  719. static TCHAR buf[12];
  720. switch (enctype) {
  721. case KERB_ETYPE_NULL:
  722. return TEXT("NULL");
  723. break;
  724. case KERB_ETYPE_DES_CBC_CRC:
  725. return TEXT("Kerberos DES-CBC-CRC");
  726. break;
  727. case KERB_ETYPE_DES_CBC_MD5:
  728. return TEXT("Kerberos DES-CBC-MD5");
  729. break;
  730. case KERB_ETYPE_RC4_MD4:
  731. return TEXT("RSADSI RC4-MD4");
  732. break;
  733. case KERB_ETYPE_RC4_PLAIN2:
  734. return TEXT("RSADSI RC4-PLAIN");
  735. break;
  736. case KERB_ETYPE_RC4_LM:
  737. return TEXT("RSADSI RC4-LM");
  738. break;
  739. case KERB_ETYPE_DES_PLAIN:
  740. return TEXT("Kerberos DES-Plain");
  741. break;
  742. #ifdef KERB_ETYPE_RC4_HMAC
  743. case KERB_ETYPE_RC4_HMAC:
  744. return TEXT("RSADSI RC4-HMAC");
  745. break;
  746. #endif
  747. case KERB_ETYPE_RC4_PLAIN:
  748. return TEXT("RSADSI RC4");
  749. break;
  750. #ifdef KERB_ETYPE_RC4_HMAC_EXP
  751. case KERB_ETYPE_RC4_HMAC_EXP:
  752. return TEXT("RSADSI RC4-HMAC(Export)");
  753. break;
  754. #endif
  755. case KERB_ETYPE_RC4_PLAIN_EXP:
  756. return TEXT("RSADSI RC4(Export)");
  757. break;
  758. case KERB_ETYPE_DES_CBC_MD5_EXP:
  759. return TEXT("Kerberos DES-CBC-MD5-EXP(Export)");
  760. break;
  761. case KERB_ETYPE_DES_PLAIN_EXP:
  762. return TEXT("Kerberos DES-Plain(Export)");
  763. break;
  764. default:
  765. _snwprintf(buf, TSIZE(buf), TEXT("etype %d"), enctype);
  766. return buf;
  767. break;
  768. }
  769. #endif
  770. }
  771. LPTSTR
  772. timestring(TimeStamp ConvertTime)
  773. /*++
  774. Routine Description:
  775. Arguments:
  776. Return Value:
  777. --*/
  778. {
  779. SYSTEMTIME SystemTime;
  780. FILETIME LocalFileTime;
  781. static TCHAR buf[LONGSTRING];
  782. if (ConvertTime.HighPart == 0x7FFFFFFF &&
  783. ConvertTime.LowPart == 0xFFFFFFFF) {
  784. return(GetStringRes(IDS_INFINITE));
  785. }
  786. if (FileTimeToLocalFileTime(
  787. (PFILETIME) &ConvertTime,
  788. &LocalFileTime) &&
  789. FileTimeToSystemTime(
  790. &LocalFileTime,
  791. &SystemTime)) {
  792. _snwprintf(buf, TSIZE(buf), ftime_default_fmt,
  793. SystemTime.wMonth,
  794. SystemTime.wDay,
  795. SystemTime.wYear,
  796. SystemTime.wHour,
  797. SystemTime.wMinute);
  798. }
  799. else
  800. return(GetStringRes(IDS_INVALID));
  801. return(buf);
  802. }
  803. // DoLockDlgRes - loads and locks a dialog template resource.
  804. // Returns the address of the locked resource.
  805. // lpszResName - name of the resource
  806. DLGTEMPLATE * WINAPI
  807. DoLockDlgRes(LPCTSTR lpszResName)
  808. /*++
  809. Routine Description:
  810. Arguments:
  811. Return Value:
  812. --*/
  813. {
  814. HRSRC hrsrc;
  815. HGLOBAL hglb;
  816. DLGTEMPLATE *pDlg;
  817. hrsrc = FindResource(NULL, lpszResName, RT_DIALOG);
  818. if (!hrsrc) {
  819. Error(TEXT("Unable to locate resource '%s'"), lpszResName);
  820. ExitProcess(0);
  821. }
  822. hglb = LoadResource(hInstance, hrsrc);
  823. if (!hglb) {
  824. Error(TEXT("Unable to load resource '%s'"), lpszResName);
  825. ExitProcess(0);
  826. }
  827. pDlg = (DLGTEMPLATE *)LockResource(hglb);
  828. if (!pDlg) {
  829. Error(TEXT("Unable to lock resource '%s'"), lpszResName);
  830. ExitProcess(0);
  831. }
  832. return pDlg;
  833. }
  834. void
  835. PurgeCache(void)
  836. /*++
  837. Routine Description:
  838. Arguments:
  839. Return Value:
  840. --*/
  841. {
  842. KERB_PURGE_TKT_CACHE_REQUEST CacheRequest;
  843. PVOID Response;
  844. ULONG ResponseSize;
  845. NTSTATUS Status, SubStatus;
  846. memset(&CacheRequest, 0, sizeof(CacheRequest));
  847. CacheRequest.MessageType = KerbPurgeTicketCacheMessage;
  848. Status = LsaCallAuthenticationPackage(LogonHandle,
  849. PackageId,
  850. &CacheRequest,
  851. sizeof(CacheRequest),
  852. &Response,
  853. &ResponseSize,
  854. &SubStatus);
  855. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  856. ShowMessage(MB_ICONINFORMATION, GetStringRes(IDS_PURGED));
  857. }
  858. else {
  859. Error(TEXT("Failed to purge ticket cache - 0x%x"), Status);
  860. }
  861. if (Response != NULL) {
  862. LsaFreeReturnBuffer(Response);
  863. }
  864. }
  865. HTREEITEM
  866. AddOneItem(
  867. HTREEITEM hParent,
  868. LPTSTR szText,
  869. HTREEITEM hInsAfter,
  870. int iImage,
  871. HWND hwndTree,
  872. LPARAM lParam
  873. )
  874. {
  875. HTREEITEM hItem;
  876. TV_ITEM tvI;
  877. TV_INSERTSTRUCT tvIns;
  878. tvI.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
  879. tvI.pszText = szText;
  880. tvI.cchTextMax = lstrlen(szText);
  881. tvI.lParam = lParam;
  882. tvI.iImage = iImage;
  883. tvI.iSelectedImage = iImage;
  884. tvIns.item = tvI;
  885. tvIns.hInsertAfter = hInsAfter;
  886. tvIns.hParent = hParent;
  887. hItem = TreeView_InsertItem(hwndTree, &tvIns);
  888. return(hItem);
  889. }
  890. HTREEITEM
  891. FindDomainByName(LPTSTR name)
  892. {
  893. HTREEITEM dom = NULL;
  894. TVITEM item;
  895. TCHAR buf[LONGSTRING];
  896. dom = TreeView_GetRoot(hWndUsers);
  897. if (!dom)
  898. return NULL;
  899. do {
  900. item.mask = TVIF_TEXT;
  901. item.pszText = buf;
  902. item.cchTextMax = sizeof(buf);
  903. item.hItem = dom;
  904. if (TreeView_GetItem(hWndUsers, &item)) {
  905. if (wcscmp(name, buf) == 0) {
  906. return dom;
  907. }
  908. }
  909. } while (dom = TreeView_GetNextSibling(hWndUsers, dom));
  910. return NULL;
  911. }
  912. HTREEITEM
  913. AddDomain(
  914. LPTSTR name
  915. )
  916. {
  917. HTREEITEM hItem;
  918. if (!(hItem = FindDomainByName(name))) {
  919. hItem = AddOneItem(NULL, _wcsdup(name), TVI_ROOT,
  920. domain_icon, hWndUsers, 0);
  921. }
  922. return(hItem);
  923. }
  924. HTREEITEM
  925. FindTicketByName(HTREEITEM lip, LPTSTR name)
  926. {
  927. HTREEITEM tick = NULL;
  928. TVITEM item;
  929. TCHAR buf[LONGSTRING];
  930. tick = TreeView_GetChild(hWndUsers, lip);
  931. if (!tick)
  932. return NULL;
  933. do {
  934. item.mask = TVIF_TEXT;
  935. item.pszText = buf;
  936. item.cchTextMax = sizeof(buf);
  937. item.hItem = tick;
  938. if (TreeView_GetItem(hWndUsers, &item)) {
  939. if (wcscmp(name, buf) == 0) {
  940. return tick;
  941. }
  942. }
  943. } while (tick = TreeView_GetNextSibling(hWndUsers, tick));
  944. return NULL;
  945. }
  946. HTREEITEM
  947. AddTicket(
  948. HTREEITEM dom,
  949. LPTSTR name,
  950. int idx,
  951. LPARAM lParam
  952. )
  953. {
  954. HTREEITEM hItem;
  955. hItem = AddOneItem(dom, name, TVI_SORT, idx, hWndUsers, lParam);
  956. TreeView_Expand(hWndUsers, dom, TVE_EXPAND);
  957. return(hItem);
  958. }
  959. void
  960. ShowTicket(
  961. HWND hDlg,
  962. PKERB_TICKET_CACHE_INFO tix,
  963. int i
  964. )
  965. /*++
  966. Routine Description:
  967. Arguments:
  968. Return Value:
  969. --*/
  970. {
  971. TCHAR sname[LONGSTRING];
  972. HTREEITEM dom, tick;
  973. FILETIME CurrentFileTime;
  974. LARGE_INTEGER Quad;
  975. long dt = 0L;
  976. memset(sname, 0, sizeof(sname));
  977. swprintf(sname, TEXT("%wZ"), &tix->RealmName);
  978. dom = AddDomain(sname);
  979. swprintf(sname, TEXT("%wZ"), &tix->ServerName);
  980. GetSystemTimeAsFileTime(&CurrentFileTime);
  981. Quad.LowPart = CurrentFileTime.dwLowDateTime;
  982. Quad.HighPart = CurrentFileTime.dwHighDateTime;
  983. dt = (long)((tix->EndTime.QuadPart - Quad.QuadPart) / TPS);
  984. // 14
  985. tick = AddTicket(dom, sname, GetIconIndex(dt), (LPARAM)tix);
  986. if (tix->TicketFlags & KERB_TICKET_FLAGS_initial)
  987. tgt = tick;
  988. }
  989. void
  990. DisplayCreds(
  991. HWND hDlg
  992. )
  993. /*++
  994. Routine Description:
  995. Arguments:
  996. Return Value:
  997. --*/
  998. {
  999. KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
  1000. PKERB_RETRIEVE_TKT_RESPONSE TicketEntry = NULL;
  1001. PKERB_EXTERNAL_TICKET Ticket;
  1002. NTSTATUS Status, SubStatus;
  1003. ULONG ResponseSize;
  1004. DWORD i;
  1005. DLGTABHDR *pHdr;
  1006. TCITEM tie;
  1007. DWORD dwDlgBase = GetDialogBaseUnits();
  1008. int cxMargin = LOWORD(dwDlgBase) / 4;
  1009. int cyMargin = HIWORD(dwDlgBase) / 8;
  1010. RECT rcTab;
  1011. pHdr = (DLGTABHDR *) LocalAlloc(LPTR|LMEM_ZEROINIT, sizeof(DLGTABHDR));
  1012. if (!pHdr)
  1013. ErrorExit(TEXT("Unable to allocate memory"));
  1014. // Save a pointer to the DLGHDR structure.
  1015. SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR)pHdr);
  1016. pHdr->hwndTab = GetDlgItem(hDlg, IDC_TAB_ATTRIBUTES);
  1017. hWndUsers = GetDlgItem(hDlg, IDC_TICKETS);
  1018. // Associate the image list with the tree view control.
  1019. //TreeView_SetImageList(hWndUsers, himl, TVSIL_NORMAL);
  1020. CacheRequest.MessageType = KerbRetrieveTicketMessage;
  1021. CacheRequest.LogonId.LowPart = 0;
  1022. CacheRequest.LogonId.HighPart = 0;
  1023. Status = LsaCallAuthenticationPackage(LogonHandle,
  1024. PackageId,
  1025. &CacheRequest,
  1026. sizeof(CacheRequest),
  1027. (PVOID *) &TicketEntry,
  1028. &ResponseSize,
  1029. &SubStatus);
  1030. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  1031. static TCHAR princ[LONGSTRING];
  1032. Ticket = &(TicketEntry->Ticket);
  1033. memset(princ, 0, sizeof(princ));
  1034. swprintf(princ, TEXT("%wZ@%wZ"),
  1035. &Ticket->ClientName->Names[0],
  1036. &Ticket->DomainName);
  1037. SetDlgItemText(hDlg, IDC_PRINC_LABEL, princ);
  1038. }
  1039. else {
  1040. SetDlgItemText(hDlg, IDC_PRINC_LABEL,
  1041. GetStringRes(IDS_NO_NET_CREDS));
  1042. SetDlgItemText(hDlg, IDC_PRINC_START,
  1043. TEXT(""));
  1044. if (TicketEntry)
  1045. LsaFreeReturnBuffer(TicketEntry);
  1046. return;
  1047. }
  1048. // Add a tab for each of the three child dialog boxes.
  1049. tie.mask = TCIF_TEXT | TCIF_IMAGE;
  1050. tie.iImage = -1;
  1051. tie.pszText = GetStringRes(IDS_LNAMES);
  1052. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_NAMES, &tie);
  1053. tie.pszText = GetStringRes(IDS_LTIMES);
  1054. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_TIMES, &tie);
  1055. tie.pszText = GetStringRes(IDS_LFLAGS);
  1056. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_FLAGS, &tie);
  1057. tie.pszText = GetStringRes(IDS_LENCTYPE);
  1058. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_ETYPES, &tie);
  1059. // Lock the resources for the three child dialog boxes.
  1060. pHdr->apRes[PPAGE_NAMES] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_NAMES));
  1061. pHdr->apRes[PPAGE_TIMES] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_TIMES));
  1062. pHdr->apRes[PPAGE_FLAGS] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_TKT_FLAGS));
  1063. pHdr->apRes[PPAGE_ETYPES] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_ENCTYPES));
  1064. // Determine the bounding rectangle for all child dialog boxes.
  1065. SetRectEmpty(&rcTab);
  1066. for (i = 0; i < C_PAGES; i++) {
  1067. if (pHdr->apRes[i]->cx > rcTab.right)
  1068. rcTab.right = pHdr->apRes[i]->cx;
  1069. if (pHdr->apRes[i]->cy > rcTab.bottom)
  1070. rcTab.bottom = pHdr->apRes[i]->cy;
  1071. }
  1072. rcTab.right = rcTab.right * LOWORD(dwDlgBase) / 4;
  1073. rcTab.bottom = rcTab.bottom * HIWORD(dwDlgBase) / 8;
  1074. // Calculate how large to make the tab control, so
  1075. // the display area can accommodate all the child dialog boxes.
  1076. TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
  1077. OffsetRect(&rcTab, cxMargin - rcTab.left,
  1078. cyMargin - rcTab.top);
  1079. // Calculate the display rectangle.
  1080. CopyRect(&pHdr->rcDisplay, &rcTab);
  1081. TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay);
  1082. CacheRequest.MessageType = KerbQueryTicketCacheMessage;
  1083. CacheRequest.LogonId.LowPart = 0;
  1084. CacheRequest.LogonId.HighPart = 0;
  1085. Status = LsaCallAuthenticationPackage(LogonHandle,
  1086. PackageId,
  1087. &CacheRequest,
  1088. sizeof(CacheRequest),
  1089. (PVOID *) &pHdr->Tickets,
  1090. &ResponseSize,
  1091. &SubStatus);
  1092. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  1093. for (i = 0; i < pHdr->Tickets->CountOfTickets; i++) {
  1094. ShowTicket(hDlg, &pHdr->Tickets->Tickets[i], i);
  1095. }
  1096. LsaFreeReturnBuffer(TicketEntry);
  1097. }
  1098. if (tgt)
  1099. TreeView_SelectItem(hWndUsers, tgt);
  1100. PropsheetDisplay(hDlg);
  1101. SelectTicket(hDlg);
  1102. }
  1103. LRESULT CALLBACK
  1104. PropSheetProc(
  1105. HWND hDlg,
  1106. UINT message,
  1107. WPARAM wParam,
  1108. LPARAM lParam
  1109. )
  1110. /*++
  1111. Routine Description:
  1112. Arguments:
  1113. Return Value:
  1114. --*/
  1115. {
  1116. DLGTABHDR *pHdr;
  1117. HWND hwndParent = GetParent(hDlg);
  1118. hwndParent = GetParent(hwndParent);
  1119. pHdr = (DLGTABHDR *) GetWindowLongPtr(hwndParent, GWLP_USERDATA);
  1120. switch (message) {
  1121. case WM_INITDIALOG:
  1122. SetWindowPos(hDlg, HWND_TOP,
  1123. pHdr->rcDisplay.left, pHdr->rcDisplay.top,
  1124. 0, 0, SWP_NOSIZE);
  1125. return TRUE;
  1126. }
  1127. return FALSE;
  1128. }
  1129. void
  1130. PropsheetDisplay(HWND hDlg)
  1131. /*++
  1132. Routine Description:
  1133. Arguments:
  1134. Return Value:
  1135. --*/
  1136. {
  1137. DLGTABHDR *pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1138. int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
  1139. // Destroy the current child dialog box, if any.
  1140. if (pHdr->hwndDisplay != NULL)
  1141. DestroyWindow(pHdr->hwndDisplay);
  1142. // Create the new child dialog box.
  1143. pHdr->hwndDisplay = CreateDialogIndirect(hInstance, pHdr->apRes[iSel],
  1144. pHdr->hwndTab, PropSheetProc);
  1145. }
  1146. INT
  1147. UnparseExternalName(
  1148. PKERB_EXTERNAL_NAME iName,
  1149. PUNICODE_STRING *np
  1150. )
  1151. {
  1152. int len, cnt;
  1153. PUNICODE_STRING name;
  1154. for (len = 0, cnt = 0; cnt < iName->NameCount; cnt++) {
  1155. len += iName->Names[cnt].Length;
  1156. if ((cnt + 1) < iName->NameCount)
  1157. len += 2;
  1158. }
  1159. name = malloc(sizeof(UNICODE_STRING));
  1160. if (!name)
  1161. return -1;
  1162. name->Buffer = malloc(len + 2);
  1163. if (!name->Buffer) {
  1164. free(name);
  1165. return -1;
  1166. }
  1167. name->Length = 0;
  1168. name->MaximumLength = len+2;
  1169. memset(name->Buffer, 0, len + 2);
  1170. for (cnt = 0; cnt < iName->NameCount; cnt++) {
  1171. wcsncat(name->Buffer, iName->Names[cnt].Buffer, iName->Names[cnt].Length/2);
  1172. name->Length += iName->Names[cnt].Length;
  1173. if ((cnt + 1) < iName->NameCount) {
  1174. wcsncat(name->Buffer, L"/", 1);
  1175. name->Length += 2;
  1176. }
  1177. }
  1178. *np = name;
  1179. return 0;
  1180. }
  1181. VOID
  1182. FreeUnicodeString(
  1183. PUNICODE_STRING ustr
  1184. )
  1185. {
  1186. if (ustr) {
  1187. free(ustr->Buffer);
  1188. free(ustr);
  1189. }
  1190. }
  1191. void
  1192. SelectTicket(HWND hDlg)
  1193. /*++
  1194. Routine Description:
  1195. Arguments:
  1196. Return Value:
  1197. --*/
  1198. {
  1199. DLGTABHDR *pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1200. int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
  1201. HTREEITEM hItem = TreeView_GetSelection(hWndUsers);
  1202. TVITEM item;
  1203. TCHAR sname[LONGSTRING];
  1204. PKERB_TICKET_CACHE_INFO tix;
  1205. FILETIME CurrentFileTime;
  1206. LARGE_INTEGER Quad;
  1207. long dt = 0L;
  1208. if (!hItem)
  1209. return;
  1210. item.hItem = hItem;
  1211. item.mask = TVIF_PARAM;
  1212. item.lParam = 0;
  1213. TreeView_GetItem(hWndUsers, &item);
  1214. if (!item.lParam) {
  1215. SetDlgItemText(hDlg, IDC_SERVICE_PRINC_LABEL,
  1216. GetStringRes(IDS_DOMAIN));
  1217. SetDlgItemText(hDlg, IDC_SERVICE_PRINC, TEXT(""));
  1218. FillinTicket(hDlg);
  1219. return;
  1220. }
  1221. SetDlgItemText(hDlg, IDC_SERVICE_PRINC_LABEL,
  1222. GetStringRes(IDS_SERVICE_PRINCIPAL));
  1223. tix = (PKERB_TICKET_CACHE_INFO)item.lParam;
  1224. GetSystemTimeAsFileTime(&CurrentFileTime);
  1225. Quad.LowPart = CurrentFileTime.dwLowDateTime;
  1226. Quad.HighPart = CurrentFileTime.dwHighDateTime;
  1227. dt = (long)((tix->EndTime.QuadPart - Quad.QuadPart) / TPS);
  1228. if (dt > 0) {
  1229. swprintf(sname, TEXT("%wZ@%wZ"),
  1230. &tix->ServerName,
  1231. &tix->RealmName);
  1232. SetDlgItemText(hDlg, IDC_SERVICE_PRINC, sname);
  1233. }
  1234. else {
  1235. SetDlgItemText(hDlg, IDC_SERVICE_PRINC_LABEL, GetStringRes(IDS_EXPIRED));
  1236. SetDlgItemText(hDlg, IDC_SERVICE_PRINC, TEXT(""));
  1237. }
  1238. FillinTicket(hDlg);
  1239. }
  1240. void
  1241. FillinTicket(HWND hDlg)
  1242. /*++
  1243. Routine Description:
  1244. Arguments:
  1245. Return Value:
  1246. --*/
  1247. {
  1248. PKERB_TICKET_CACHE_INFO tix;
  1249. DLGTABHDR *pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1250. int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
  1251. HTREEITEM hItem = TreeView_GetSelection(hWndUsers);
  1252. TVITEM item;
  1253. PKERB_RETRIEVE_TKT_REQUEST TicketRequest;
  1254. ULONG ResponseSize;
  1255. NTSTATUS Status, SubStatus;
  1256. PKERB_EXTERNAL_TICKET ticket;
  1257. int sz;
  1258. TCHAR sname[LONGSTRING];
  1259. PUNICODE_STRING svc;
  1260. if (!hItem)
  1261. return;
  1262. item.hItem = hItem;
  1263. item.mask = TVIF_PARAM;
  1264. item.lParam = 0;
  1265. TreeView_GetItem(hWndUsers, &item);
  1266. switch(iSel) {
  1267. case PPAGE_NAMES:
  1268. SetDlgItemText(pHdr->hwndDisplay, IDC_SERVICENAME,
  1269. TEXT(""));
  1270. SetDlgItemText(pHdr->hwndDisplay, IDC_TARGETNAME,
  1271. TEXT(""));
  1272. SetDlgItemText(pHdr->hwndDisplay, IDC_CLIENTNAME,
  1273. TEXT(""));
  1274. break;
  1275. case PPAGE_TIMES:
  1276. SetDlgItemText(pHdr->hwndDisplay, IDC_STARTTIME,
  1277. TEXT(""));
  1278. SetDlgItemText(pHdr->hwndDisplay, IDC_ENDTIME,
  1279. TEXT(""));
  1280. SetDlgItemText(pHdr->hwndDisplay, IDC_RENEW_UNTIL,
  1281. TEXT(""));
  1282. break;
  1283. case PPAGE_ETYPES:
  1284. SetDlgItemText(pHdr->hwndDisplay, IDC_TKT_ENCTYPE,
  1285. TEXT(""));
  1286. SetDlgItemText(pHdr->hwndDisplay, IDC_KEY_ENCTYPE,
  1287. TEXT(""));
  1288. break;
  1289. case PPAGE_FLAGS:
  1290. ShowFlags(pHdr->hwndDisplay, 0);
  1291. break;
  1292. }
  1293. if (!item.lParam) {
  1294. return;
  1295. }
  1296. tix = (PKERB_TICKET_CACHE_INFO)item.lParam;
  1297. swprintf(sname, TEXT("%wZ@%wZ"),
  1298. &tix->ServerName,
  1299. &tix->RealmName);
  1300. sz = sizeof(WCHAR)*(wcslen(sname) + 1);
  1301. TicketRequest = LocalAlloc(LMEM_ZEROINIT,
  1302. sizeof(KERB_RETRIEVE_TKT_REQUEST) + sz);
  1303. if (!TicketRequest)
  1304. ErrorExit(TEXT("Unable to allocate memory"));
  1305. TicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
  1306. TicketRequest->LogonId.LowPart = 0;
  1307. TicketRequest->LogonId.HighPart = 0;
  1308. TicketRequest->TargetName.Length = wcslen(sname) * sizeof(WCHAR);
  1309. TicketRequest->TargetName.MaximumLength = TicketRequest->TargetName.Length + sizeof(WCHAR);
  1310. TicketRequest->TargetName.Buffer = (LPWSTR) (TicketRequest + 1);
  1311. wcsncpy(TicketRequest->TargetName.Buffer, sname, wcslen(sname));
  1312. TicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_USE_CACHE_ONLY;
  1313. TicketRequest->EncryptionType = 0L;
  1314. TicketRequest->TicketFlags = 0L;
  1315. Status = LsaCallAuthenticationPackage(LogonHandle,
  1316. PackageId,
  1317. TicketRequest,
  1318. (sizeof(KERB_RETRIEVE_TKT_REQUEST) + sz),
  1319. (PVOID *)&ticket,
  1320. &ResponseSize,
  1321. &SubStatus);
  1322. LocalFree(TicketRequest);
  1323. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  1324. #if 0
  1325. if (ticket->TargetName && ticket->TargetDomainName.Length &&
  1326. !UnparseExternalName(ticket->TargetName, &svc)) {
  1327. swprintf(sname, TEXT("%wZ@%wZ"),
  1328. svc,
  1329. &ticket->TargetDomainName);
  1330. SetDlgItemText(hDlg, IDC_SERVICE_PRINC, sname);
  1331. SetDlgItemText(hDlg, IDC_SERVICE_PRINC_LABEL,
  1332. GetStringRes(IDS_TARGET_NAME));
  1333. FreeUnicodeString(svc);
  1334. }
  1335. #endif
  1336. switch(iSel) {
  1337. case PPAGE_NAMES:
  1338. if (ticket->ServiceName && ticket->DomainName.Length &&
  1339. !UnparseExternalName(ticket->ServiceName, &svc)) {
  1340. swprintf(sname, TEXT("%wZ@%wZ"),
  1341. svc,
  1342. &ticket->DomainName);
  1343. SetDlgItemText(pHdr->hwndDisplay, IDC_SERVICENAME,
  1344. sname);
  1345. FreeUnicodeString(svc);
  1346. }
  1347. if (ticket->ClientName && ticket->DomainName.Length &&
  1348. !UnparseExternalName(ticket->ClientName, &svc)) {
  1349. swprintf(sname, TEXT("%wZ@%wZ"),
  1350. svc,
  1351. &ticket->DomainName);
  1352. SetDlgItemText(pHdr->hwndDisplay, IDC_CLIENTNAME,
  1353. sname);
  1354. FreeUnicodeString(svc);
  1355. }
  1356. if (ticket->TargetName && ticket->TargetDomainName.Length &&
  1357. !UnparseExternalName(ticket->TargetName, &svc)) {
  1358. swprintf(sname, TEXT("%wZ@%wZ"),
  1359. svc,
  1360. &ticket->TargetDomainName);
  1361. SetDlgItemText(pHdr->hwndDisplay, IDC_TARGETNAME,
  1362. sname);
  1363. FreeUnicodeString(svc);
  1364. }
  1365. break;
  1366. case PPAGE_TIMES:
  1367. SetDlgItemText(pHdr->hwndDisplay, IDC_STARTTIME,
  1368. timestring(tix->StartTime));
  1369. SetDlgItemText(pHdr->hwndDisplay, IDC_ENDTIME,
  1370. timestring(tix->EndTime));
  1371. if (tix->TicketFlags & KERB_TICKET_FLAGS_renewable) {
  1372. SetDlgItemText(pHdr->hwndDisplay, IDC_RENEW_UNTIL,
  1373. timestring(tix->RenewTime));
  1374. ShowWindow(GetDlgItem(pHdr->hwndDisplay, IDC_RENEW_UNTIL),
  1375. SW_SHOW);
  1376. }
  1377. else {
  1378. ShowWindow(GetDlgItem(pHdr->hwndDisplay, IDC_RENEW_UNTIL),
  1379. SW_HIDE);
  1380. }
  1381. break;
  1382. case PPAGE_ETYPES:
  1383. SetDlgItemText(pHdr->hwndDisplay, IDC_TKT_ENCTYPE,
  1384. etype_string(tix->EncryptionType));
  1385. SetDlgItemText(pHdr->hwndDisplay, IDC_KEY_ENCTYPE,
  1386. etype_string(ticket->SessionKey.KeyType));
  1387. break;
  1388. case PPAGE_FLAGS:
  1389. ShowFlags(pHdr->hwndDisplay, tix->TicketFlags);
  1390. break;
  1391. }
  1392. LsaFreeReturnBuffer(ticket);
  1393. }
  1394. }
  1395. LRESULT CALLBACK
  1396. TicketsProc(
  1397. HWND hDlg,
  1398. UINT message,
  1399. WPARAM wParam,
  1400. LPARAM lParam
  1401. )
  1402. /*++
  1403. Routine Description:
  1404. Arguments:
  1405. Return Value:
  1406. --*/
  1407. {
  1408. LPNMHDR nm;
  1409. DLGTABHDR *pHdr;
  1410. switch (message) {
  1411. case WM_INITDIALOG:
  1412. DisplayCreds(hDlg);
  1413. ShowWindow(hDlg, SW_SHOW);
  1414. return TRUE;
  1415. case WM_NOTIFY: {
  1416. nm = (LPNMHDR)lParam;
  1417. switch (nm->code) {
  1418. case TCN_SELCHANGING:
  1419. return FALSE;
  1420. case TCN_SELCHANGE:
  1421. PropsheetDisplay(hDlg);
  1422. FillinTicket(hDlg);
  1423. return TRUE;
  1424. case TVN_SELCHANGED:
  1425. SelectTicket(hDlg);
  1426. break;
  1427. }
  1428. }
  1429. break;
  1430. case WM_SYSCOMMAND:
  1431. switch (wParam) {
  1432. case SC_CLOSE:
  1433. goto close_tix;
  1434. }
  1435. break;
  1436. case WM_COMMAND:
  1437. switch (LOWORD(wParam)) {
  1438. case IDC_CLOSE:
  1439. close_tix:
  1440. pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1441. if (pHdr->hwndDisplay != NULL)
  1442. DestroyWindow(pHdr->hwndDisplay);
  1443. DestroyWindow(hDlgTickets);
  1444. LsaFreeReturnBuffer(pHdr->Tickets);
  1445. LocalFree(pHdr);
  1446. hDlgTickets = NULL;
  1447. break;
  1448. }
  1449. break;
  1450. }
  1451. return FALSE;
  1452. }
  1453. void
  1454. Tickets(void)
  1455. /*++
  1456. Routine Description:
  1457. Arguments:
  1458. Return Value:
  1459. --*/
  1460. {
  1461. if (!hDlgTickets)
  1462. hDlgTickets = CreateDialog(hInstance,
  1463. MAKEINTRESOURCE(IDD_TICKETS),
  1464. hWnd,
  1465. TicketsProc);
  1466. else {
  1467. ShowWindow(hDlgTickets, SW_SHOW);
  1468. SetForegroundWindow(hDlgTickets);
  1469. }
  1470. }