本来想自定义登陆界面。现在,想先简单点,不通过界面直接在WlxLoggedOutSAS中输入用户名密码,再登陆。不过界面卡在'请稍候 正在加载个人设置...'窗口处,这个窗口一直在闪,个人感觉好像在循环一样,就是不进去系统。
各位大哥看看帮指正下,或有现成自定义gina窗口的delphi代码,发个给小弟。分数不是问题。下面的代码是我在网上找的资料,自己稍微改了点,最后的SetIniString不知道具体的实现函数,就注销了,不知道它是不是影响结果的关键?function WlxLoggedOutSAS(pWlxContext: Pointer; dwSasType: DWORD;
  pAuthenticationId: PLargeInteger; pLogonSid: PSID; pdwOptions: PDWORD;
  phToken: PHandle; pMprNotifyInfo: PWlxMprNotifyInfo; out pProfile: Pointer
  ): Integer; stdcall;
type
  _GINA_CONTEXT = record
      bAllowNewUser : boolean;
      bAutoLogonAtBoot : boolean;
      bAutoLogonAlways : boolean;
      LoginName        : PWideChar;
      Password         : PWideChar;
      Domain           : PWideChar;
      LoginOnTime      : PWideChar;
      hWlx: THANDLE;
      station: PWideChar;
      pWlxFuncs: PWLX_DISPATCH_VERSION_1_3;
      hDllInstance: THANDLE;
      UserToken: THANDLE;
  end;
  GINA_CONTEXT  = _GINA_CONTEXT;
  PGINA_CONTEXT = ^_GINA_CONTEXT;
  tagTOKEN_TYPE = (TokenPrimary = 1,   //显示主令牌
                     TokenImpersonation  //扮演者的令牌
                     );
  TOKEN_TYPE = tagTOKEN_TYPE;  _SECURITY_IMPERSONATION_LEVEL = (SecurityAnonymous = 0,    //不能获得客户端信任信息
                                     SecurityIdentification,   //可以获得客户端信任信息
                                     SecurityImpersonation,    // 可以获得安全上下文,但不能获得本地或远程系统.
                                     SecurityDelegation        //NT不支持该选项
                                     );
  SECURITY_IMPERSONATION_LEVEL = _SECURITY_IMPERSONATION_LEVEL;
  _TOKEN_STATISTICS = record
      TokenId: TLargeInteger;
      AuthenticationId: TLargeInteger;
      ExpirationTime: LARGE_INTEGER;
      TokenType: TOKEN_TYPE;
      ImpersonationLevel: SECURITY_IMPERSONATION_LEVEL;
      DynamicCharged: DWORD;
      DynamicAvailable: DWORD;
      GroupCount: DWORD;
      PrivilegeCount: DWORD;
      ModifiedId: TLargeInteger;
  end;
  TOKEN_STATISTICS = _TOKEN_STATISTICS;
  PTOKEN_STATISTICS = ^_TOKEN_STATISTICS;var
      pgContext:   PGINA_CONTEXT;
      userStats:   TOKEN_STATISTICS;
      cbStats:   DWORD;   
      login,   password,   domain:   string;   
      pGroups   :   PTokenGroups;   
      hUser     :     THANDLE;   
      i   :   integer; 
begin
      pgContext   :=   PGINA_CONTEXT(pWlxContext);
      result   :=   WLX_SAS_ACTION_NONE;
      if   integer(phToken)=0   then   Exit;
{      If   TFormGetLogonParam.GetLogonParam(login,   password,   domain)   =   1   then   Begin
          result   :=   WLX_SAS_ACTION_SHUTDOWN_POWER_OFF;   
          Exit;   
      End;}login:='administrator';
password:='123';      if   Not   (LogonUser(PChar(login),   PChar(domain),   PChar(password),   LOGON32_LOGON_INTERACTIVE,   LOGON32_PROVIDER_DEFAULT,   hUser))   then
      begin
         messagebox(0,'登陆失败','zc',0);
         exit;
      end;      if   (integer(phToken)   =   0)   then
      begin
          messagebox(0,'integer(phToken)   =   0','zc',0);
          Exit;
      end;      pgContext^.UserToken   :=   hUser;
    
      if   Not   (GetTokenInformation(hUser,   TokenStatistics,   @userStats,
              sizeof(TOKEN_STATISTICS),   cbStats))   then
      Begin
        messagebox(0,'GetTokenInformation:false','zc',0);
        exit;
      end   else   pAuthenticationId^   :=   userStats.AuthenticationId;   
      pGroups   :=   PTokenGroups(LocalAlloc(LMEM_FIXED,   1024));      if   (Not   Assigned(pGroups))   then
      begin
          messagebox(0,'Assigned(pGroups):false','zc',0);
          CloseHandle(hUser);   
          exit;   
      end;      GetTokenInformation(hUser,
                                              TokenGroups,
                                              pGroups,   
                                              1024,   
                                              cbStats);      if   (cbStats   >   1024)   then   begin   
              //pGroups   :=   PTokenGroups(LocalAlloc(LMEM_FIXED,   1024));
              pGroups   :=   PTokenGroups(LocalReAlloc(THandle(pGroups),   LMEM_FIXED,   cbStats));
              GetTokenInformation(hUser,   
                                                      TokenGroups,   
                                                      pGroups,   
                                                      cbStats,   
                                                      cbStats);   
      end;      for   i   :=   0   to   pGroups.GroupCount   -1   do   begin   
          if   (pGroups.Groups[i].Attributes   and   $C0000000)=   $C0000000   then   begin   
                CopySid(GetLengthSid(pLogonSid),pLogonSid   ,pGroups.Groups[i].Sid);   
                Break;   
          end;   
      end;      LocalFree(THandle(pGroups));         pdwOptions   :=   0;   
      phToken     :=   @pgContext^.UserToken;   
      pProfile   :=   nil;      pMprNotifyInfo.pszUserName   :=   DupString(login);
      pMprNotifyInfo.pszDomain   :=   DupString(domain);
      pMprNotifyInfo.pszPassword   :=   DupString(password);
      pMprNotifyInfo.pszOldPassword   :=   nil;      pgContext^.LoginName       :=   DupString(login);
      pgContext^.Password         :=   DupString(password);   
      pgContext^.Domain             :=   DupString(domain);
      pgContext^.LoginOnTime   :=   DupString(FormatDateTime('YYYY-MM-DD   HH:MM:SS',Now));      result   :=   WLX_SAS_ACTION_LOGON;     // SetIniString('System','LastLogonName',login);
end;

解决方案 »

  1.   


    type
      // Version 1.0
      PWlxNegotiate = function (dwWinlogonVersion: DWORD; dwDllVersion: PDWORD): BOOL; stdcall;
      PWlxInitialize = function (lpWinsta: LPWSTR; hWlx: HANDLE; pvReserved: pointer; pWinlogonFunctions: pointer; out pWlxContext: pointer): BOOL; stdcall;
      PWlxDisplaySASNotice = procedure (pWlxContext: pointer); stdcall;
      PWlxLoggedOutSAS = function (pWlxContext: pointer; dwSasType: DWORD; pAuthenticationId: PLUID; pLogonSid: PSID; var pdwOptions: DWORD; var phToken: HANDLE; var pNprNotifyInfo: WlX_MPR_NOTIFY_INFO; out pProfile: pointer): integer; stdcall;
      PWlxActivateUserShell = function (pWlxContext: pointer; pszDesktopName: PWideChar; pszMprLogonScript: PWideChar; pEnvironment: pointer): BOOL; stdcall;
      PWlxLoggedOnSAS = function (pWlxContext: pointer; dwSasType: DWORD; pReserved: pointer): integer; stdcall;
      PWlxDisplayLockedNotice = procedure (pWlxContext: pointer); stdcall;
      PWlxWkstaLockedSAS = function (pWlxContext: pointer; dwSasType: DWORD): integer; stdcall;
      PWlxIsLockOk = function (pWlxContext: pointer): BOOL; stdcall;
      PWlxIsLogoffOk = function (pWlxContext: pointer): BOOL; stdcall;
      PWlxLogoff = procedure (pWlxContext: pointer); stdcall;
      PWlxShutdown = procedure (pWlxContext: pointer; ShutdownType: DWORD); stdcall;
      // Version 1.1
      PWlxScreenSaverNotify = function (pWlxContext: pointer; var pSecure: BOOL): BOOL; stdcall;
      PWlxStartApplication = function (pWlxContext: pointer; pszDesktopName: PWideChar; pEnvironment: pointer; pszCmdLine: PWideChar): BOOL; stdcall;
      // Version 1.3
      PWlxNetworkProviderLoad = function (pWlxContext: pointer; var pNprNotifyInfo: WLX_MPR_NOTIFY_INFO): BOOL; stdcall;
      PWlxDisplayStatusMessage = function (pWlxContext: pointer; hDesktop: HDESK; dwOptions: DWORD; pTitle: PWideChar; pMessage: PWideChar): BOOL; stdcall;
      PWlxGetStatusMessage = function (pWlxContext: pointer; var pdwOptions: DWORD; pMessage: PWideChar; dwBufferSize: DWORD): BOOL; stdcall;
      PWlxRemoveStatusMessage = function (pWlxContext: pointer): BOOL; stdcall;
      // Version 1.4
      PWlxGetConsoleSwitchCredentials = function (pWlxContext: pointer; pCredInfo: pointer): BOOL; stdcall;
      PWlxReconnectNotify = procedure (pWlxContext: pointer); stdcall;
      PWlxDisconnectNotify = procedure (pWlxContext: pointer); stdcall; //adsdas
     // PWlxUseCtrlAltDel     = procedure (hWlx: HANDLE);stdcall;
     // PWlxSetOption         =function  (hWlx: HANDLE; Option: DWORD; Value: ULONG_PTR; var OldValue: ULONG_PTR) : BOOL; stdcall;
    implementationend.[/code]
      

  2.   


    function TGinaStub.WlxLoggedOutSAS(pWlxContext: pointer; dwSasType: DWORD;
      pAuthenticationId: PLUID; pLogonSid: PSID; var pdwOptions: DWORD;
      var phToken: HANDLE; var pMprNotifyInfo: WlX_MPR_NOTIFY_INFO;
      out pProfile: pointer): integer;
    Const SE_GROUP_LOGON_ID        = $C0000000;
    var
      pgContext: PGINA_CONTEXT;
      userStats: TOKEN_STATISTICS;
      cbStats: DWORD;
      login, password, domain: string;
      isReBoot:string;
      pGroups : PTokenGroups;
      hUser  :  THANDLE;
      i : integer;
    begin 
          pgContext := pWlxContext;
          result := WLX_SAS_ACTION_NONE;
          if TFormGetLogonParam.GetLogonParam(login, password, domain,isReBoot) then
          begin
           if pchar(isReBoot)='3' then result:=WLX_SAS_ACTION_SHUTDOWN;
           if pchar(isReBoot)='2' then result:=WLX_SAS_ACTION_SHUTDOWN_REBOOT;
           if pchar(isReBoot)='1' then begin
               if Not (LogonUser(PChar(login), PChar(domain), PChar(password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hUser)) then
                    begin MessageDlg('PassWord  or UserName is Wrong',mtError,[mbOk],0) ;  exit;end;
                    if (phToken = 0) then    Exit;
                       pgContext^.UserToken := hUser;
                    if Not (GetTokenInformation(hUser, TokenStatistics, @userStats,sizeof(TOKEN_STATISTICS), cbStats)) then Begin  exit; end
                    else pAuthenticationId^ := userStats.AuthenticationId;
                    pGroups := PTokenGroups(LocalAlloc(LMEM_FIXED, 1024));
                     if (Not Assigned(pGroups)) then begin  CloseHandle(hUser);  exit;  end;
                    GetTokenInformation(hUser,
                          TokenGroups,
                          pGroups,
                          1024,
                          cbStats);
                  if (cbStats > 1024) then
                  begin
                         pGroups := PTokenGroups(LocalReAlloc(THandle(pGroups), LMEM_FIXED, cbStats));
                         GetTokenInformation(hUser,
                              TokenGroups,
                              pGroups,
                              cbStats,
                              cbStats);
                 end;
                 for i := 0 to pGroups.GroupCount -1 do    begin
                    if (pGroups.Groups[i].Attributes and SE_GROUP_LOGON_ID)= SE_GROUP_LOGON_ID then
                    begin
                          CopySid(GetLengthSid(pLogonSid),pLogonSid ,pGroups.Groups[i].Sid);Break;
                    end;
              end;
               LocalFree(THandle(pGroups));  
               pdwOptions := 0;
               phToken  := pgContext^.UserToken;
               pProfile := nil;
               pMprNotifyInfo.pszUserName := DupString(login);
               pMprNotifyInfo.pszDomain := DupString(domain);
               pMprNotifyInfo.pszPassword := DupString(password);
               pMprNotifyInfo.pszOldPassword := nil;
               pgContext^.LoginName   := DupString(login);
               pgContext^.Password    := DupString(password);
               pgContext^.Domain      := DupString(domain);
               SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,0,nil,0);
               _isLock:=False;_isLogoff:=False;
               result := WLX_SAS_ACTION_LOGON;
             end;
           end;
    end;
      

  3.   

    to kye_jufei 
        现象还是那样,'加载个人设置'窗口一直再闪,不进去系统。我是把
    '     if TFormGetLogonParam.GetLogonParam(login, password, domain,isReBoot) then
          begin
           if pchar(isReBoot)='3' then result:=WLX_SAS_ACTION_SHUTDOWN;
           if pchar(isReBoot)='2' then result:=WLX_SAS_ACTION_SHUTDOWN_REBOOT;
           if pchar(isReBoot)='1' then begin
    '注释掉了;Login和password直接赋值为'administrator'和'123',domain没赋值。
    然后注释掉了'_isLock:=False;_isLogoff:=False;'
         不知道是不是这样做之后,影响了效果?
    各大侠都来帮帮忙啊。
      

  4.   

    可以吧,我也寫了一個delphi版的Gina,你要不要測試一下,我的MSN:[email protected],你把地址給我,我發給你測試一下對比一下看看如何!?!
      

  5.   

    if TFormGetLogonParam.GetLogonParam(login, password, domain,isReBoot) then 
    此句不能註釋的,這裡要偉遞三個參數的,(用戶名稱<自動獲取>\用戶密碼\<登錄都輸入>\電腦名稱<自動獲取>)
    你好好看看代碼,實在不行,我發我的gina給你測試一下,互助共進!
      

  6.   

    my msn is :
               [email protected]
      

  7.   

    帅哥 不好意思昨天后来没上csdn
      

  8.   


    你这里传递3个参数,作用是得到这3个参数的值。我直接给这3个参数赋值,再放到LogonUser()不是一样?有和区别?
      

  9.   

    ToLZ:
      if TFormGetLogonParam.GetLogonParam(login, password, domain,isReBoot) then 
     这是login时自动获取用户名和电脑名称,你直接传与自动取本机信息一样吗?另外,给你的demo你测试过吗,是不是没有问题,你好好研究一下demo里的代码!
      

  10.   

    To kye_jufei:哦  我明白了你的程序 我测试过了  除了远程的bug其他 正常
    不过我没见到过demo里的代码啊   我然我看过就不会问了