AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Windows Dialog "Verbindung zu xyz wird hergestellt" erzeugen
Thema durchsuchen
Ansicht
Themen-Optionen

Windows Dialog "Verbindung zu xyz wird hergestellt" erzeugen

Offene Frage von "gi_networx"
Ein Thema von gi_networx · begonnen am 27. Sep 2006 · letzter Beitrag vom 28. Sep 2006
Antwort Antwort
Benutzerbild von gi_networx
gi_networx

Registriert seit: 2. Feb 2006
27 Beiträge
 
#1

Windows Dialog "Verbindung zu xyz wird hergestellt"

  Alt 27. Sep 2006, 09:29
Hi ihr,

ihr kennt doch sicher alle diesen Standard-Login-Dialog der erscheint wenn man z.B. mit dem Internet-Epxlorer versucht auf eine per htaccess geschützte Ressource auf einem Webserver zuzugreifen.

Kann man diesen Dialog per API erzeugen und danach auswerten (und weiterverabeiten) was der Benutzer als Username und Kennwort eingegeben hat?

Ich schreibe im Moment ein Programm das u.a. auf Netzwerkshares zugreift. Wenn ich jetzt einen eigenen Dialog für Benutzername und Kennwort erstelle kennt sich wieder kein Anwender aus, wenn er den Standard-Dialog von Windows sieht weiß er wohl schon eher was/welche Accountdaten er dort einzugeben hat...

Bei Google bin ich immer wieder auf msgina.dll gestossen, aber so wie ich das verstanden habe ist diese nur für den Anmelde-Dialog bei Windows und den Dialog bei Strg+Alt+Entf zuständig (? klärt mich auf wenn ich falsch liege).

Gruß
Michl
  Mit Zitat antworten Zitat
Benutzerbild von timog
timog

Registriert seit: 26. Sep 2006
Ort: Landkreis Oldenburg (Oldb)
117 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 27. Sep 2006, 09:34
Hi Michl,

keine Antwort, aber bringt Dir das BS nicht den Zugriffsdialog automatisch, wenn Du auf ein passwortgeschütztes Networkshare zugreifst? Wieso brauchst Du den Dialog direkt in Deinem Proggi?

Viele Grüße

Timo
Timo
  Mit Zitat antworten Zitat
Benutzerbild von gi_networx
gi_networx

Registriert seit: 2. Feb 2006
27 Beiträge
 
#3

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 27. Sep 2006, 10:08
Hi,

ich muss ehrlich gestehen das ich das noch nicht ausprobiert habe.
Aber ich glaube zu wissen das Delphi eine Fehlermeldung verursacht wenn man etwas wie TStringList.SaveToFile('\\server\protected$\foo.ba r'); macht.

Gruß
Michl
  Mit Zitat antworten Zitat
Benutzerbild von timog
timog

Registriert seit: 26. Sep 2006
Ort: Landkreis Oldenburg (Oldb)
117 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#4

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 27. Sep 2006, 11:10
Okay, Denkfehler bei mir.

Gesucht wird die API für CredUIPromptForCredentials

Lösungsvorschlag: Marcel van Brakels Win32API runterladen: http://delphi-jedi.org/APILIBRARY

Dort gibt es die JwaWinCred.pas, die eigentlich alles enthalten sollte.

Die Passwörter musst Du dann wohl noch mit
WNetAddConnection(PChar(resourcename),PChar(password),'') bzw. entsprechendes mit WNetAddConnection2 übergeben.

Hoffe, das hilft Dir weiter.

Viele Grüße

Timo
Timo
  Mit Zitat antworten Zitat
Benutzerbild von timog
timog

Registriert seit: 26. Sep 2006
Ort: Landkreis Oldenburg (Oldb)
117 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#5

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 27. Sep 2006, 11:28
Vielleicht auch noch von Interesse ist das Beispiel aus borland.public.delphi.nativeapi.win32. Dafür werden jedoch die Komponenten von TNTware.com benötigt - das wichtigste steht aber schön im Quelltext.

Viel Erfolg damit!

Timo

PS: Lass mal hören, ob es geklappt hat.
Timo
  Mit Zitat antworten Zitat
Benutzerbild von gi_networx
gi_networx

Registriert seit: 2. Feb 2006
27 Beiträge
 
#6

Super!

  Alt 27. Sep 2006, 11:32
Vielen Dank, das ist genau das was ich gesucht habe!

Werde evtl. heute Nachmittag dann mal posten ob ich es erfolgreich in meine Anwendung integrieren konnte! Ein kurzer Foo-Test hat jedenfalls einwandfrei geklappt!

Gruß
Michl
  Mit Zitat antworten Zitat
Benutzerbild von gi_networx
gi_networx

Registriert seit: 2. Feb 2006
27 Beiträge
 
#7

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 27. Sep 2006, 17:13
Hi,

ich habe jetzt noch folgendes Problem:

ich übergebe Windowz einen Array [0...X] of Char als Usernamen den es im Login-Dialog anzeigen soll.
Genau in diesen Array schreibt Windows ja nach dem der User auf OK/abbrechen geklickt hat auch wieder den Wert der im Feld "Benutzername" steht.

Ich initialisiere den Array mit "foobar". Windowz zeigt also im Login-Dialog bereits im Feld Benutzername den Wert "foobar".
Wir nehmen jetzt mal an das der User den Wert "foobar" entfernt und als Benutzernamen "123" eingibt.

Nachdem der User auf OK/Abbrechen geklickt hat steht aber in dem Array _nicht_ nur "123" sondern "123bar".
Windowz überschreibt also anscheinend den Array von Pos 0 an mit dem Benutzernamen den der User angegeben hat, füllt den Array aber danach nicht mit #0 auf.

D.h. ich kann nach dem anzeigen des Dialogs nicht feststellen was der User wirklich eingegeben hat falls der eingegebene Wert kürzer als der initialisierte Wert des Arrays ist.

Kennt jemand eine Lösung für dieses Problem?
  Mit Zitat antworten Zitat
Benutzerbild von timog
timog

Registriert seit: 26. Sep 2006
Ort: Landkreis Oldenburg (Oldb)
117 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#8

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 28. Sep 2006, 07:07
Hi,

okay... Aber warum nicht einfach einen WideString? Muss es ein Array of Char sein? Hast Du Dir mal das Beispiel aus der Newsgroup bei Google angeschaut (Post #5)? Dort ist doch ein ganz nettes Beispiel für eine Delphi-Kapselung drin. Vielleicht einen Blick wert? Benötigt halt nur die Unicode Komponenten...

Viel Erfolg

Timo
Timo
Real Programmers are surprised when the odometers in their cars don't turn from 99999 to 9999A.
  Mit Zitat antworten Zitat
Benutzerbild von gi_networx
gi_networx

Registriert seit: 2. Feb 2006
27 Beiträge
 
#9

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 28. Sep 2006, 08:12
ich verwende im Moment folgenden Code:

Delphi-Quellcode:
var
  UserName: array [0..CRED_MAX_USERNAME_LENGTH] of Char;
  i: Integer;

...

ZeroMemory(@UserName, SizeOf(UserName));
for i:=0 to length(preuser) do UserName[i] := preuser[i+1]; //preUser ist ein String mit dem Usernamen der bereits im Dialog angezeigt werden soll

errcode := CredUIPromptForCredentials(@Info, 'Foo', nil, 0,
      @UserName, CRED_MAX_USERNAME_LENGTH+1,
      Password, CREDUI_MAX_PASSWORD_LENGTH+1,
      Save, Flag);

for i:=0 to CRED_MAX_USERNAME_LENGTH do if Username[i] <> #0 then struser := struser + Username[i]; //struser ist ein string der den usernamen _nach_ dem anzeigen des dialogs enthalten soll
damit habe ich oben erwähntes problemn.
wie meinst du denn das mit dem WideString? CredUIPromptForCredentials verlangt doch als Usernamen einen PChar...
  Mit Zitat antworten Zitat
Benutzerbild von timog
timog

Registriert seit: 26. Sep 2006
Ort: Landkreis Oldenburg (Oldb)
117 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#10

Re: Windows Dialog "Verbindung zu xyz wird hergestellt&

  Alt 28. Sep 2006, 11:57
Stimmt schon, hatte an einen Typecast mit PChar(strUsername) gedacht. Hier einmal eine Beispiel unit (nicht von mir, sondern nur angepasst aus der Newsgroupdiskussion).

Delphi-Quellcode:
unit uSBD_LogOn2;

interface

uses Classes, Windows, Dialogs;

type
   TUserTestResult = (rFail, rPass, rCancel);

const
   Default_LogOnDlgTitle = '';
   Default_LogOnDlgCaption = '';

type
   TLogOnDialog = class( TCommonDialog)
     private
       FUserName : widestring;
       FDomain : widestring;
       FPassword : widestring;
       FTitle : widestring;
       FPrompt : widestring;
       FLogOnResult: TUserTestResult;
       FuseLocalAdmin: boolean;
       function DoExecute: boolean;
     public
       constructor Create( AOwner: TComponent); override;
       function Execute: Boolean; override;
       procedure Burn;
       property Password : widestring read FPassword write FPassword;
       property LogOnResult: TUserTestResult read FLogOnResult write FLogOnResult;
     published
       property UserName : widestring read FUserName write FUserName;
       property Domain : widestring read FDomain write FDomain;
       property Title : widestring read FTitle write FTitle;
       property Prompt : widestring read FPrompt write FPrompt;
       property useLocalAdministrators: boolean read FuseLocalAdmin write FuseLocalAdmin;
   end;

// TO DO: Get the list of administrator UserName/Domain.

implementation
// Refer:
// [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seca[/url]...
// security/impersonateloggedonuser.asp
// [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seca[/url]...
// security/logonuser.asp
// [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seca[/url]...
// security/creduipromptforcredentials.asp
// [url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secbp/[/url]
// security/asking_the_user_for_credentials.asp

uses SysUtils;

type
   TCredUI_InfoA = packed record
     cbSize: DWord;
     hwndParent: HWND;
     pszMessageText: PAnsiChar;
     pszCaptionText: PAnsiChar;
     hbmBanner: HBitMap
     end;
   PCredUI_InfoA = ^TCredUI_InfoA;


   TCredUI_InfoW = packed record
     cbSize: DWord;
     hwndParent: HWND;
     pszMessageText: PWideChar;
     pszCaptionText: PWideChar;
     hbmBanner: HBitMap
     end;
   PCredUI_InfoW = ^TCredUI_InfoW;

   TCredUIPromptForCredentials_FuncA = function(
     var pUiInfo: TCredUI_InfoA;
     pszTargetname: PAnsiChar;
     Reserved: THandle;
     dsAuthError: DWord;
     pszUersName: PAnsiChar;
     ulUserNameMaxChars: ulong;
     pszPassword: PAnsiChar;
     ulPasswordMaxChars: ulong;
     var pfSave: bool;
     dwFlags: DWord): DWord; stdcall;

   TCredUIPromptForCredentials_FuncW = function(
     var pUiInfo: TCredUI_InfoW;
     pszTargetname: PWideChar;
     Reserved: THandle;
     dsAuthError: DWord;
     pszUersName: PWideChar;
     ulUserNameMaxChars: ulong;
     pszPassword: PWideChar;
     ulPasswordMaxChars: ulong;
     var pfSave: bool;
     dwFlags: DWord): DWord; stdcall;

// StrLenLimit: Scan Src for a null terminator up to MaxLen bytes
function StrLenLimit(Src: PChar; MaxLen: Cardinal): Cardinal;
begin
   if Src = nil then
   begin
     Result := 0;
     Exit;
   end;
   Result := MaxLen;
   while (Src^ <> #0) and (Result > 0) do
   begin
     Inc(Src);
     Dec(Result);
   end;
   Result := MaxLen - Result;
end;

procedure BurnWideString( var SensitiveValue: widestring);
var
   L: integer;
begin
  L := Length( SensitiveValue);
  if L = 0 then exit;
  FillChar( SensitiveValue, L * SizeOf( WideChar), #0);
  SensitiveValue := ''
end;

type
   TDialogFunc = function( var DialogData): Bool stdcall;

function Global_DialogFunc ( var DialogData): Bool stdcall;
begin
  result := TLogOnDialog( DialogData).DoExecute
end;

 { TLogOnDialog }

procedure TLogOnDialog.Burn;
begin
  BurnWideString( FUsername);
  BurnWideString( FDomain);
  BurnWideString( FPassword)
end;

constructor TLogOnDialog.Create( AOwner: TComponent);
begin
  inherited;
  FUserName := '';
  FDomain := '';
  FPassword := '';
  FTitle := Default_LogOnDlgTitle;
  FPrompt := Default_LogOnDlgCaption;
  FLogOnResult := rCancel;
  FuseLocalAdmin := False
end;

const
   CRED_MAX_GENERIC_TARGET_NAME_LENGTH = 32767;
   CRED_MAX_DOMAIN_TARGET_NAME_LENGTH = 256 + 1 + 80;
   CRED_MAX_USERNAME_LENGTH = 256 + 1 + 256;
   CRED_MAX_CREDENTIAL_BLOB_SIZE = 512;
   CREDUI_MAX_MESSAGE_LENGTH = 32767;
   CREDUI_MAX_CAPTION_LENGTH = 128;
   CREDUI_MAX_GENERIC_TARGET_LENGTH = CRED_MAX_GENERIC_TARGET_NAME_LENGTH;
   CREDUI_MAX_DOMAIN_TARGET_LENGTH = CRED_MAX_DOMAIN_TARGET_NAME_LENGTH;
   CREDUI_MAX_USERNAME_LENGTH = CRED_MAX_USERNAME_LENGTH;
   CREDUI_MAX_PASSWORD_LENGTH = CRED_MAX_CREDENTIAL_BLOB_SIZE div 2;
   CREDUI_FLAGS_INCORRECT_PASSWORD = $00001; // indicates the username is valid, but password is not
   CREDUI_FLAGS_DO_NOT_PERSIST = $00002; // Do not show "Save" checkbox, and do not persist credentials
   CREDUI_FLAGS_REQUEST_ADMINISTRATOR = $00004; // Populate list box with admin accounts
   CREDUI_FLAGS_EXCLUDE_CERTIFICATES = $00008; // do not include certificates in the drop list
   CREDUI_FLAGS_REQUIRE_CERTIFICATE = $00010;
   CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX = $00040;
   CREDUI_FLAGS_ALWAYS_SHOW_UI = $00080;
   CREDUI_FLAGS_REQUIRE_SMARTCARD = $00100;
   CREDUI_FLAGS_PASSWORD_ONLY_OK = $00200;
   CREDUI_FLAGS_VALIDATE_USERNAME = $00400;
   CREDUI_FLAGS_COMPLETE_USERNAME = $00800;
   CREDUI_FLAGS_PERSIST = $01000; // Do not show "Save" checkbox, but persist credentials anyway
   CREDUI_FLAGS_SERVER_CREDENTIAL = $04000;
   CREDUI_FLAGS_EXPECT_CONFIRMATION = $20000; // do not persist unless caller later confirms credential via CredUIConfirmCredential() api
   CREDUI_FLAGS_GENERIC_CREDENTIALS = $40000; // Credential is a generic credential
   CREDUI_FLAGS_USERNAME_TARGET_CREDENTIALS = $80000; // Credential has a username as the target
   CREDUI_FLAGS_KEEP_USERNAME = $100000; // don't allow the user to change the supplied username

procedure PrepareStringBufferW( var Buffer: widestring;
   const Source: widestring; MaxLen: integer);
var
   L: integer;
begin
  SetLength( Buffer, MaxLen);
  UniqueString( Buffer);
  FillChar( Buffer[1], MaxLen * SizeOf( WideChar), #0);
  L := Length( Source);
  if L > MaxLen then
      L := MaxLen;
  if L > 0 then
     Move( Source[1], Buffer[1], L * SizeOf( WideChar))
end;

function TLogOnDialog.DoExecute: boolean;
var
   hCredui: THandle;
   CredUIPromptForCredentials_FuncW: TCredUIPromptForCredentials_FuncW;
   CredUI_InfoW: TCredUI_InfoW;
   pfSave: bool;
   wTargetname: widestring;
   wUserName: widestring;
   wPassword: widestring;
   DlgResult: DWord;
   Lib: HMODULE;
   dwFlags: DWord;

begin
  Lib := 0;
  pfSave := False;
  wTargetname := FDomain;
  UniqueString( wTargetName);
  PrepareStringBufferW( wUserName, FUserName, CREDUI_MAX_USERNAME_LENGTH);
  PrepareStringBufferW( wPassword, ''       , CREDUI_MAX_PASSWORD_LENGTH);
  CredUI_InfoW.cbSize := SizeOf( CredUI_InfoW);
  CredUI_InfoW.hwndParent := 0;
  CredUI_InfoW.pszMessageText := PWideChar( FPrompt );
  CredUI_InfoW.pszCaptionText := PWideChar( FTitle);
  CredUI_InfoW.hbmBanner := 0;
  dwFlags := CREDUI_FLAGS_ALWAYS_SHOW_UI + CREDUI_FLAGS_DO_NOT_PERSIST +
            CREDUI_FLAGS_GENERIC_CREDENTIALS;
  if FuseLocalAdmin then
    Inc( dwFlags, CREDUI_FLAGS_REQUEST_ADMINISTRATOR);
    hCredui := GetModuleHandle( 'credui.dll');
  try
   if hCredui <> 0 then
     CredUIPromptForCredentials_FuncW := GetProcAddress( hCredui,'CredUIPromptForCredentialsW')
   else
     begin
     Lib := windows.LoadLibrary( 'credui.dll');
     if Lib <> 0 then
         CredUIPromptForCredentials_FuncW := GetProcAddress( Lib,
               'CredUIPromptForCredentialsW')
       else
         CredUIPromptForCredentials_FuncW := nil
     end;
   if assigned( CredUIPromptForCredentials_FuncW) then
     begin
     DlgResult := CredUIPromptForCredentials_FuncW(
       CredUI_InfoW, PWideChar( wTargetname), 0, 0, PWideChar( wUserName),
       CREDUI_MAX_USERNAME_LENGTH + 1, PWideChar( wPassword),
       CREDUI_MAX_PASSWORD_LENGTH + 1, pfSave, dwFlags);
     SetLength( wUserName, Length( PWideChar( wUserName)));
     SetLength( wPassword, Length( PWideChar( wPassword)));
     case DlgResult of
       ERROR_CANCELLED:
         begin
         FLogOnResult := rCancel;
         result := False
         end;
       NO_ERROR :
         begin
         FLogOnResult := rPass;
         result := True;
         FUserName := wUserName;
         FPassword := wPassword
         end;
       ERROR_INVALID_FLAGS, ERROR_INVALID_PARAMETER,
       ERROR_NO_SUCH_LOGON_SESSION:
         begin
         FLogOnResult := rFail;
         result := False
         end;
       else
         begin
         FLogOnResult := rFail;
         result := False
         end
       end
     end
   else
     begin
     FLogOnResult := rFail;
     result := False
     end
  finally
   if Lib <> 0 then
     windows.FreeLibrary( Lib)
  end
end;

function TLogOnDialog.Execute: Boolean;
var
  SelfRef: TLogOnDialog;
begin
  FLogOnResult := rCancel;
  SelfRef := self;
  result := TaskModalDialog( @Global_DialogFunc, SelfRef)
end;

end.
Und der Aufruf dann so:
Delphi-Quellcode:
procedure TformMain.Button1Click(Sender: TObject);
var
   Dlg: TLogOnDialog;
begin
  Dlg := TLogOnDialog.Create( nil);
  try
    Dlg.Title := Application.Title;
    Dlg.Prompt := 'Bitte Benutzernamen eingeben';
    Dlg.UserName := 'Administrator';
    Dlg.useLocalAdministrators := True;
    if Dlg.Execute then
      begin
        Memo1.Lines.Add(Dlg.UserName);
        Memo1.Lines.Add(Dlg.Domain);
        Memo1.Lines.Add(Dlg.Password);
      end
    else
      Memo1.Lines.Add('Abbruch');
  finally
    Dlg.Free
  end
end;

Klappt bei mir ohne Probleme...

Viel Erfolg noch!

Timo
Timo
Real Programmers are surprised when the odometers in their cars don't turn from 99999 to 9999A.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:09 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz