LOGON.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:20k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //+---------------------------------------------------------------------------
  2. //
  3. //  Microsoft Windows
  4. //  Copyright 1992 - 1997 Microsoft Corporation.
  5. //
  6. //  File:       logon.c
  7. //
  8. //  Contents:
  9. //
  10. //  Classes:
  11. //
  12. //  Functions:
  13. //
  14. //  History:    4-28-95   RichardW   Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "gina.h"
  18. #pragma hdrstop
  19. HIMAGELIST      hiLogonSmall;
  20. HIMAGELIST      hiLogonLarge;
  21. PMiniAccount    pAccountList;
  22. WCHAR           szMiniKey[] = TEXT("Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Accounts");
  23. BYTE            LongPseudoRandomString[] = {0x27, 0xbd, 0xff, 0xa0,
  24.                                             0xaf, 0xbf, 0x00, 0x1c,
  25.                                             0x24, 0x0e, 0x00, 0x01,
  26.                                             0x24, 0x0f, 0x00, 0x05 };
  27. MiniAccount TestAccounts[]  = { {NULL, TEXT("daveth"), TEXT("\msft\risc\dev"), TEXT("daveth"), TEXT("Oooh"), 0, MINI_CAN_EDIT},
  28.                                 {NULL, TEXT("Test1"), TEXT("Redmond"), TEXT("Test1"), TEXT("Mine"), 0, MINI_CAN_EDIT},
  29.                                 {NULL, TEXT("Test2"), TEXT("NtWksta"), TEXT("Test2"), TEXT("Yours"), 0, 0},
  30.                                 {NULL, TEXT("New User"), TEXT(""), TEXT(""), TEXT(""), 0, MINI_NEW_ACCOUNT}
  31.                               };
  32. BOOL
  33. SaveMiniAccount(PMiniAccount    pAccount)
  34. {
  35.     HKEY                    hMiniKey;
  36.     PSerializedMiniAccount  pPacked;
  37.     DWORD                   cbNeeded;
  38.     PWSTR                   pszPack;
  39.     int                     err;
  40.     DWORD                   Disposition;
  41.     err = RegCreateKeyEx(   HKEY_LOCAL_MACHINE,
  42.                             szMiniKey,
  43.                             0,
  44.                             TEXT(""),
  45.                             REG_OPTION_NON_VOLATILE,
  46.                             KEY_WRITE | KEY_READ,
  47.                             NULL,
  48.                             &hMiniKey,
  49.                             &Disposition);
  50.     if (err)
  51.     {
  52.         return(FALSE);
  53.     }
  54.     cbNeeded = sizeof(SerializedMiniAccount) +
  55.                 (wcslen(pAccount->pszDomain) + 1 +
  56.                  wcslen(pAccount->pszPassword) + 1 +
  57.                  wcslen(pAccount->pszComment) + 1 ) * sizeof(WCHAR) ;
  58.     pPacked = LocalAlloc(LMEM_FIXED, cbNeeded);
  59.     if (!pPacked)
  60.     {
  61.         return(FALSE);
  62.     }
  63.     pszPack = (PWSTR) (pPacked + 1);
  64.     pPacked->Version = MINI_VERSION;
  65.     pPacked->Flags = pAccount->Flags;
  66.     pPacked->IconId = pAccount->IconId;
  67.     pPacked->dwDomainOffset = sizeof(SerializedMiniAccount);
  68.     pPacked->dwDomainLength = (wcslen(pAccount->pszDomain) + 1) * sizeof(WCHAR);
  69.     wcscpy(pszPack, pAccount->pszDomain);
  70.     pszPack += (pPacked->dwDomainLength / sizeof(WCHAR) );
  71.     pPacked->dwPasswordOffset = pPacked->dwDomainOffset + pPacked->dwDomainLength;
  72.     pPacked->dwPasswordLength = (wcslen(pAccount->pszPassword) + 1) * sizeof(WCHAR);
  73.     wcscpy(pszPack, pAccount->pszPassword);
  74.     pszPack += (pPacked->dwPasswordLength / sizeof(WCHAR) );
  75.     pPacked->dwCommentOffset = pPacked->dwPasswordOffset + pPacked->dwPasswordLength;
  76.     pPacked->dwCommentLength = (wcslen(pAccount->pszComment) + 1) * sizeof(WCHAR);
  77.     wcscpy(pszPack, pAccount->pszComment);
  78.     err = RegSetValueEx(hMiniKey,
  79.                         pAccount->pszUsername,
  80.                         0,
  81.                         REG_BINARY,
  82.                         (PBYTE) pPacked,
  83.                         cbNeeded);
  84.     RegCloseKey(hMiniKey);
  85.     return(err == 0);
  86. }
  87. BOOL
  88. LoadMiniAccounts(PGlobals   pGlobals)
  89. {
  90.     FILETIME            LastWrite;
  91.     // HKEY                hKey;
  92.     HKEY                hMiniKey;
  93.     WCHAR               szClass[64];
  94.     DWORD               err;
  95.     DWORD               Disposition;
  96.     DWORD               Class;
  97.     DWORD               cKeys;
  98.     DWORD               LongestKeyName;
  99.     DWORD               LongestClass;
  100.     DWORD               cValues;
  101.     DWORD               LongestValueName;
  102.     DWORD               LongestValueData;
  103.     DWORD               Security;
  104.     DWORD               i;
  105.     WCHAR               szValue[MAX_PATH];
  106.     DWORD               cbValue;
  107.     DWORD               dwType;
  108.     DWORD               cbData;
  109.     PBYTE               pBuffer;
  110.     DWORD               cbBuffer;
  111.     PMiniAccount        pAccount;
  112.     PSerializedMiniAccount  pPacked;
  113.     if (pGlobals->fAllowNewUser)
  114.     {
  115.         pAccount = LocalAlloc(LMEM_FIXED, sizeof(MiniAccount) );
  116.         if (pAccount)
  117.         {
  118.             pAccount->pNext = NULL;
  119.             pAccount->pszUsername = TEXT("New User");
  120.             pAccount->pszDomain = TEXT("");
  121.             pAccount->pszPassword = TEXT("");
  122.             pAccount->pszComment = TEXT("");
  123.             pAccount->Flags = MINI_NEW_ACCOUNT;
  124.             pAccountList = pAccount;
  125.         }
  126.         else
  127.             return(FALSE);
  128.     }
  129.     else
  130.     {
  131.         pAccountList = NULL;
  132.     }
  133.     //
  134.     //
  135.     err = RegCreateKeyEx(   HKEY_LOCAL_MACHINE,
  136.                             szMiniKey,
  137.                             0,
  138.                             TEXT(""),
  139.                             REG_OPTION_NON_VOLATILE,
  140.                             KEY_WRITE | KEY_READ,
  141.                             NULL,
  142.                             &hMiniKey,
  143.                             &Disposition);
  144.     if (err)
  145.     {
  146.         return(FALSE);
  147.     }
  148.     if (Disposition == REG_OPENED_EXISTING_KEY)
  149.     {
  150.         //
  151.         // Enumerate the sub keys of our class, and Load them.
  152.         //
  153.         Class = sizeof(szClass) / sizeof(WCHAR);
  154.         err = RegQueryInfoKey(  hMiniKey,
  155.                                 szClass,
  156.                                 &Class,
  157.                                 NULL,
  158.                                 &cKeys,
  159.                                 &LongestKeyName,
  160.                                 &LongestClass,
  161.                                 &cValues,
  162.                                 &LongestValueName,
  163.                                 &LongestValueData,
  164.                                 &Security,
  165.                                 &LastWrite);
  166.         pBuffer = LocalAlloc(LMEM_FIXED, 512);
  167.         cbBuffer = 512;
  168.         for (i = 0; i < cValues ; i++ )
  169.         {
  170.             cbValue = MAX_PATH;
  171.             err = RegEnumValue( hMiniKey,
  172.                                 i,
  173.                                 szValue,
  174.                                 &cbValue,
  175.                                 NULL,
  176.                                 &dwType,
  177.                                 NULL,
  178.                                 &cbData);
  179.             if (err)
  180.             {
  181.                 break;
  182.             }
  183.             if (dwType != REG_BINARY)
  184.             {
  185.                 continue;
  186.             }
  187.             if (cbData > cbBuffer)
  188.             {
  189.                 pBuffer = LocalReAlloc(pBuffer, LMEM_FIXED, cbData);
  190.                 if (!pBuffer)
  191.                 {
  192.                     break;
  193.                 }
  194.                 cbBuffer = cbData;
  195.             }
  196.             err = RegQueryValueEx(  hMiniKey,
  197.                                     szValue,
  198.                                     0,
  199.                                     &dwType,
  200.                                     pBuffer,
  201.                                     &cbData);
  202.             if (err == 0)
  203.             {
  204.                 pPacked = (PSerializedMiniAccount) pBuffer;
  205.                 if (pPacked->Version != MINI_VERSION)
  206.                 {
  207.                     continue;
  208.                 }
  209.                 pAccount = LocalAlloc(LMEM_FIXED, sizeof(MiniAccount));
  210.                 if (pAccount)
  211.                 {
  212.                     pAccount->Flags = pPacked->Flags;
  213.                     pAccount->IconId = pPacked->IconId;
  214.                     pAccount->pszUsername = LocalAlloc(LMEM_FIXED, (cbValue+1)*sizeof(TCHAR));
  215.                     if (pAccount->pszUsername)
  216.                     {
  217.                         wcscpy(pAccount->pszUsername, szValue);
  218.                     }
  219.                     pAccount->pszDomain = LocalAlloc(LMEM_FIXED, pPacked->dwDomainLength);
  220.                     if (pAccount->pszDomain)
  221.                     {
  222.                         wcscpy(pAccount->pszDomain,
  223.                                (PWSTR) ((pBuffer) + pPacked->dwDomainOffset) );
  224.                     }
  225.                     pAccount->pszPassword = LocalAlloc(LMEM_FIXED, pPacked->dwPasswordLength);
  226.                     if (pAccount->pszPassword)
  227.                     {
  228.                         wcscpy(pAccount->pszPassword,
  229.                                (PWSTR) (pBuffer + pPacked->dwPasswordOffset) );
  230.                     }
  231.                     pAccount->pszComment = LocalAlloc(LMEM_FIXED, pPacked->dwCommentLength);
  232.                     if (pAccount->pszComment)
  233.                     {
  234.                         wcscpy(pAccount->pszComment,
  235.                                (PWSTR) (pBuffer + pPacked->dwCommentOffset) );
  236.                     }
  237.                     pAccount->pNext = pAccountList;
  238.                     pAccountList = pAccount;
  239.                 }
  240.             }
  241.         }
  242.     }
  243.     return(TRUE);
  244. }
  245. VOID
  246. InitializeImageLists()
  247. {
  248.     HICON   hIcon;
  249.     hiLogonSmall = ImageList_Create(16, 16, TRUE, 4, 0);
  250.     hiLogonLarge = ImageList_Create(32, 32, TRUE, 4, 0);
  251.     hIcon = LoadIcon(hDllInstance, MAKEINTRESOURCE(IDI_USER_ICON));
  252.     if (!hIcon)
  253.     {
  254.         DebugLog((DEB_ERROR, "Unable to load icon, %dn", GetLastError()));
  255.     }
  256.     ImageList_AddIcon(hiLogonLarge, hIcon);
  257.     ImageList_AddIcon(hiLogonSmall, hIcon);
  258.     hIcon = LoadIcon(hDllInstance, MAKEINTRESOURCE(IDI_NEW_USER_ICON));
  259.     ImageList_AddIcon(hiLogonLarge, hIcon);
  260.     ImageList_AddIcon(hiLogonSmall, hIcon);
  261. }
  262. PopulateListView(
  263.     HWND            hLV,
  264.     PMiniAccount    pAccList)
  265. {
  266.     LV_ITEM     lvi;
  267.     LV_COLUMN   lvc;
  268.     DWORD       Count;
  269.     ListView_SetImageList(hLV, hiLogonLarge, LVSIL_NORMAL);
  270.     ListView_SetImageList(hLV, hiLogonSmall, LVSIL_SMALL);
  271.     //
  272.     // Ok, now set up the columns for the list view
  273.     //
  274.     lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  275.     lvc.fmt = LVCFMT_LEFT;
  276.     lvc.cx = 0;
  277.     lvc.iSubItem = 0;
  278.     lvc.pszText = TEXT("Name        ");
  279.     ListView_InsertColumn(hLV, 0, &lvc);
  280.     lvc.iSubItem = 1;
  281.     lvc.pszText = TEXT("Domain   ");
  282.     ListView_InsertColumn(hLV, 1, &lvc);
  283.     //
  284.     // Comment
  285.     //
  286.     lvc.iSubItem = 2;
  287.     lvc.pszText = TEXT("Comment   ");
  288.     ListView_InsertColumn(hLV, 2, &lvc);
  289.     lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  290.     Count = 0;
  291.     while (pAccList)
  292.     {
  293.         lvi.iItem = Count;
  294.         lvi.iSubItem  = 0;
  295.         lvi.iImage = (pAccList->Flags & MINI_NEW_ACCOUNT) ? 1 : 0;
  296.         lvi.pszText = pAccList->pszUsername;
  297.         lvi.lParam = (LPARAM) pAccList;
  298.         ListView_InsertItem(hLV, &lvi);
  299.         ListView_SetItemText(hLV, Count, 1, pAccList->pszDomain);
  300.         ListView_SetItemText(hLV, Count, 2, pAccList->pszComment);
  301.         Count++;
  302.         pAccList = pAccList->pNext;
  303.     }
  304.     return(TRUE);
  305. }
  306. int
  307. CALLBACK
  308. NewUserDlgProc(
  309.     HWND    hDlg,
  310.     UINT    Message,
  311.     WPARAM  wParam,
  312.     LPARAM  lParam)
  313. {
  314.     PGlobals        pGlobals;
  315.     PMiniAccount    pMini;
  316.     pGlobals = (PGlobals) GetWindowLong(hDlg, GWL_USERDATA);
  317.     switch (Message)
  318.     {
  319.         case WM_INITDIALOG:
  320.             CenterWindow(hDlg);
  321.             SetWindowLong(hDlg, GWL_USERDATA, lParam);
  322.             return(TRUE);
  323.         case WM_COMMAND:
  324.             if (LOWORD(wParam) == IDOK)
  325.             {
  326.                 pMini = LocalAlloc(LMEM_FIXED, sizeof(MiniAccount));
  327.                 pMini->pszUsername = AllocAndCaptureText(hDlg, IDD_USER_NAME);
  328.                 pMini->pszDomain = AllocAndCaptureText(hDlg, IDD_DOMAIN);
  329.                 pMini->pszPassword = AllocAndCaptureText(hDlg, IDD_PASSWORD);
  330.                 pMini->pszComment = DupString(TEXT(""));
  331.                 pMini->Flags = MINI_SAVE | MINI_CAN_EDIT;
  332.                 pMini->IconId = 0;
  333.                 pMini->pNext = pAccountList;
  334.                 pAccountList = pMini;
  335.                 pGlobals->pAccount = pMini;
  336.                 EndDialog(hDlg, IDOK);
  337.             }
  338.             if (LOWORD(wParam) == IDCANCEL)
  339.             {
  340.                 EndDialog(hDlg, IDCANCEL);
  341.             }
  342.             return(TRUE);
  343.     }
  344.     return(FALSE);
  345. }
  346. LogonDlgInit(
  347.     HWND    hDlg,
  348.     LPARAM  lParam)
  349. {
  350.     PGlobals        pGlobals;
  351.     HWND            hLV;
  352.     pGlobals = (PGlobals) lParam;
  353.     SetWindowLong(hDlg, GWL_USERDATA, lParam);
  354.     pGlobals->pAccount = NULL;
  355.     if (pAccountList == NULL)
  356.     {
  357.         LoadMiniAccounts(pGlobals);
  358.     }
  359.     InitializeImageLists();
  360.     hLV = GetDlgItem(hDlg, IDD_LOGON_LV);
  361.     PopulateListView(hLV, pAccountList);
  362.     CenterWindow(hDlg);
  363.     ListView_SetColumnWidth(hLV, 0, LVSCW_AUTOSIZE);
  364.     ListView_SetColumnWidth(hLV, 1, LVSCW_AUTOSIZE);
  365.     ListView_SetColumnWidth(hLV, 2, LVSCW_AUTOSIZE);
  366.     ShowWindow(hLV, SW_NORMAL);
  367.     EnableWindow(hLV, TRUE);
  368.     EnableWindow(GetDlgItem(hDlg, IDD_LOGON_BUTTON), FALSE);
  369.     return(TRUE);
  370. }
  371. int
  372. HandleLvNotify(
  373.     HWND        hDlg,
  374.     PGlobals    pGlobals,
  375.     NMHDR *     pNMH)
  376. {
  377.     NM_LISTVIEW *   pNotify;
  378.     LV_ITEM         lvi;
  379.     HWND            hLV;
  380.     PMiniAccount *  ppAcc;
  381.     int             ret;
  382.     int             index;
  383.     pNotify = (NM_LISTVIEW *) pNMH;
  384.     hLV = GetDlgItem(hDlg, IDD_LOGON_LV);
  385.     ppAcc = &pGlobals->pAccount;
  386.     switch (pNotify->hdr.code)
  387.     {
  388.         case NM_CLICK:
  389.         case NM_DBLCLK:
  390.             EnableWindow(GetDlgItem(hDlg, IDD_LOGON_BUTTON), TRUE);
  391.             index = ListView_GetNextItem(hLV, -1, LVNI_SELECTED);
  392.             if (index >= 0)
  393.             {
  394.                 lvi.iItem = index;
  395.                 lvi.iSubItem = 0;
  396.                 lvi.mask = LVIF_PARAM;
  397.                 ret = ListView_GetItem(hLV, &lvi);
  398.                 *ppAcc = (PMiniAccount) lvi.lParam;
  399.                 DebugLog((DEB_TRACE, "Selected Item %d, lParam = %xn", index, lvi.lParam));
  400.             }
  401.             if (pNotify->hdr.code == NM_DBLCLK)
  402.             {
  403.                 PostMessage(hDlg, WM_COMMAND, IDOK, 0);
  404.             }
  405.             return(TRUE);
  406.     }
  407.     return(FALSE);
  408. }
  409. int
  410. CALLBACK
  411. LogonDlgProc(
  412.     HWND        hDlg,
  413.     UINT        Message,
  414.     WPARAM      wParam,
  415.     LPARAM      lParam)
  416. {
  417.     NMHDR *     pNotifyHeader;
  418.     PGlobals    pGlobals;
  419.     int         result;
  420.     pGlobals = (PGlobals) GetWindowLong(hDlg, GWL_USERDATA);
  421.     switch (Message)
  422.     {
  423.         case WM_INITDIALOG:
  424.             return(LogonDlgInit(hDlg, lParam));
  425.         case WM_COMMAND:
  426.             if (LOWORD(wParam) == IDCANCEL)
  427.             {
  428.                 EndDialog(hDlg, WLX_SAS_ACTION_NONE);
  429.             }
  430.             if (LOWORD(wParam) == IDD_LOGON_BUTTON)
  431.             {
  432.                 if (pGlobals->pAccount->Flags & MINI_NEW_ACCOUNT)
  433.                 {
  434.                     result = pWlxFuncs->WlxDialogBoxParam(  hGlobalWlx,
  435.                                                             hDllInstance,
  436.                                                             (LPTSTR) MAKEINTRESOURCE(IDD_NEW_USER_LOGON),
  437.                                                             hDlg,
  438.                                                             (DLGPROC) NewUserDlgProc,
  439.                                                             (LPARAM) pGlobals);
  440.                 }
  441.                 else
  442.                 {
  443.                     result = IDOK;
  444.                 }
  445.                 if (result == IDOK)
  446.                 {
  447.                     EndDialog(hDlg, WLX_SAS_ACTION_LOGON);
  448.                 }
  449.             }
  450.             if (LOWORD(wParam) == IDD_SHUTDOWN_BUTTON)
  451.             {
  452.                 result = pWlxFuncs->WlxDialogBoxParam(  hGlobalWlx,
  453.                                                         hDllInstance,
  454.                                                         (LPTSTR) MAKEINTRESOURCE(IDD_SHUTDOWN),
  455.                                                         hDlg,
  456.                                                         (DLGPROC) ShutdownDlgProc,
  457.                                                         (LPARAM) pGlobals);
  458.                 if (result != WLX_SAS_ACTION_NONE)
  459.                 {
  460.                     EndDialog(hDlg, result);
  461.                 }
  462.             }
  463.             return(TRUE);
  464.             break;
  465.         case WM_NOTIFY:
  466.             pNotifyHeader = (NMHDR *) lParam;
  467.             if (wParam == IDD_LOGON_LV)
  468.             {
  469.                 return(HandleLvNotify(hDlg, pGlobals, pNotifyHeader));
  470.             }
  471.         case WM_CLOSE:
  472.             hiLogonSmall = NULL;
  473.             hiLogonLarge = NULL;
  474.             return(TRUE);
  475.     }
  476.     return(FALSE);
  477. }
  478. ///////////////////////////////////////////////////////////////////////////
  479. ///////////////////////////////////////////////////////////////////////////
  480. //
  481. //
  482. //
  483. ///////////////////////////////////////////////////////////////////////////
  484. ///////////////////////////////////////////////////////////////////////////
  485. int
  486. AttemptLogon(
  487.     PGlobals        pGlobals,
  488.     PMiniAccount    pAccount,
  489.     PSID            pLogonSid,
  490.     PLUID           pLogonId)
  491. {
  492.     HANDLE              hUser;
  493.     TOKEN_STATISTICS    TStats;
  494.     TOKEN_GROUPS    *   pGroups;
  495.     DWORD               size;
  496.     DWORD               i;
  497.     if (LogonUser(  pAccount->pszUsername,
  498.                     pAccount->pszDomain,
  499.                     pAccount->pszPassword,
  500.                     LOGON32_LOGON_INTERACTIVE,
  501.                     LOGON32_PROVIDER_DEFAULT,
  502.                     &hUser))
  503.     {
  504.         if (pAccount->Flags & MINI_SAVE)
  505.         {
  506.             SaveMiniAccount(pAccount);
  507.             pAccount->Flags &= ~MINI_SAVE;
  508.         }
  509.         pGlobals->hUserToken = hUser;
  510.         //
  511.         // Now, grovel the token we got back for interesting stuff:
  512.         //
  513.         GetTokenInformation(hUser,
  514.                             TokenStatistics,
  515.                             &TStats,
  516.                             sizeof(TStats),
  517.                             &size);
  518.         *pLogonId = TStats.AuthenticationId;
  519.         pGroups = LocalAlloc(LMEM_FIXED, 1024);
  520.         if (!pGroups)
  521.         {
  522.             CloseHandle(hUser);
  523.             return(WLX_SAS_ACTION_NONE);
  524.         }
  525.         //
  526.         // The tricky part.  We need to get the Logon SID from the token,
  527.         // since that is what Winlogon will use to protect the windowstation
  528.         // and desktop.
  529.         //
  530.         GetTokenInformation(hUser,
  531.                             TokenGroups,
  532.                             pGroups,
  533.                             1024,
  534.                             &size);
  535.         if (size > 1024)
  536.         {
  537.             pGroups = LocalReAlloc(pGroups, LMEM_FIXED, size);
  538.             GetTokenInformation(hUser,
  539.                                 TokenGroups,
  540.                                 pGroups,
  541.                                 size,
  542.                                 &size);
  543.         }
  544.         for (i = 0; i < pGroups->GroupCount ; i++)
  545.         {
  546.             if ((pGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
  547.             {
  548.                 CopySid(GetLengthSid(pLogonSid),
  549.                         pLogonSid,
  550.                         pGroups->Groups[i].Sid );
  551.                 break;
  552.             }
  553.         }
  554.         LocalFree(pGroups);
  555.         return(WLX_SAS_ACTION_LOGON);
  556.     }
  557.     return(WLX_SAS_ACTION_NONE);
  558. }