Ir para conteúdo
Fórum Script Brasil
  • 0

Pegar Usuarios Da Rede


fajo

Pergunta

8 respostass a esta questão

Posts Recomendados

  • 0
Guest Visitante

To usando essa aqui, mas num aparece nada no listbox:

procedure TForm4.Button1Click(Sender: TObject);

var

hEnum, dwResult, dwResultEnum : DWORD;

lpnrLocal : array

[0..16384 div SizeOf(TNetResource)] of TNetResource; // ponteiro para as estruturas enumeradas

i : integer;

cEntries : Longint;

cbBuffer: DWORD;

begin

Screen.Cursor := crHourGlass;

centries := -1; // enumera todas as entradas possíveis

cbBuffer := 16384; // 16K

// chama a função WNetOpenEnum para inciar a enumeração.

dwResult := WNetOpenEnum(

RESOURCE_CONTEXT, // Enumera o recursos atualmente conectados.

RESOURCETYPE_DISK, // todos os recursos

0, // enumera todos os recursos

nil, // NULL

hEnum // handle para os recursos

);

if (dwResult <> NO_ERROR) then

begin

// poderia processar os erros com um manipulador de erros

// definido na aplicação.

Exit;

end;

// inicializa o buffer.

FillChar( lpnrLocal, cbBuffer, 0 );

// chama a função WNetEnumResource para continuar a enumeração

dwResultEnum := WNetEnumResource(hEnum, // manipulador

DWORD(cEntries), // definido localmente como -1

@lpnrLocal, // LPNETRESOURCE

cbBuffer); // tamanho do buffer

ListBox1.Clear;

// preencho uma listbox

for i := 0 to cEntries - 1 do

begin

// lê cada estrutura para pegar o nome do

// recurso remoto (lpnrLocal.lpRemoteName)

ListBox1.Items.Add( lpnrLocal.lpRemoteName );

end;

// chama WNetCloseEnum para finalizar a enumeração.

dwResult := WNetCloseEnum(hEnum);

screen.Cursor := crDefault;

end;

Link para o comentário
Compartilhar em outros sites

  • 0

Já verificou se dwResult não está retornando algo diferente de NO_ERROR?

Pões um break-point na linha: if (dwResult <> NO_ERROR) then e, quando ele parar nela, executa passo-a-passo (F8) para verificar se ele não está saindo da procedure pelo Exit.

Como disse antes, só vai obter sucesso se você estiver logado com uma conta de administrador.

Link para o comentário
Compartilhar em outros sites

  • 0
To usando essa aqui, mas num aparece nada no listbox:

procedure TForm4.Button1Click(Sender: TObject);

var

hEnum, dwResult, dwResultEnum : DWORD;

lpnrLocal : array

[0..16384 div SizeOf(TNetResource)] of TNetResource; // ponteiro para as estruturas enumeradas

i : integer;

cEntries : Longint;

cbBuffer: DWORD;

begin

Screen.Cursor := crHourGlass;

centries := -1; // enumera todas as entradas possíveis

cbBuffer := 16384; // 16K

// chama a função WNetOpenEnum para inciar a enumeração.

dwResult := WNetOpenEnum(

RESOURCE_CONTEXT, // Enumera o recursos atualmente conectados.

RESOURCETYPE_DISK, // todos os recursos

0, // enumera todos os recursos

nil, // NULL

hEnum // handle para os recursos

);

...

end;

fajo, copiei seu código e realmente não lista nada, nem ocorre erro como eu sugerí no post anterior.

Entretanto, conferindo no msdn os parâmetros da função, observei que o primeiro parâmetro só pode ter os seguintes valores:

RESOURCE_CONNECTED - All currently connected resources (the dwUsage parameter is ignored).

RESOURCE_GLOBALNET - All resources on the network.

RESOURCE_REMEMBERED - All remembered (persistent) connections (the dwUsage parameter is ignored). These connections may or may not currently be connected.

Logo, pelo comentário no código, o 1º parâmetro dever ser RESOURCE_CONNECTED e não RESOURCE_CONTEXT.

Fazendo a alteração, o que obtive foi a relação dos path's dos discos mapeados na minha máquina, ou seja, pastas compartilhadas em outros micros da rede as quais eu mapei.

Acho que não é isto que você está procurando.

Fuçando aqui e ali, lá no msdn, cheguei na função NetWkstaUserEnum (link), até pensei em implementar algo, mas o Google tá ai para que, né? :D

Tem um exemplo prontinho na página do Torry's. Acho que com ele você consegue ajustar o seu programa.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Grande Micheus, beleza

obrigado pela grande ajuda que você vem me dando;

o código do Torry's não funcionou, mas, encontrei um outro:

*** CODE START ***

unit Example_Unit;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls;

//Declaration of the returning structures.

//These are part of LanMan 2.x and are not supported by Delphi.

//Translated from C++ code in the SDK help files.

//As you can see we are using lpWStr instead of the C++ lpTStr

Type

_WKSTA_USER_INFO_0 = Record

User_Name : Array[0..255] Of lpWStr;

End;

Type

_WKSTA_USER_INFO_1 = Record

User_Name,

Logon_Domain,

Other_Domains,

Logon_Server : Array[0..255] Of lpWStr;

End;

Type

WKSTA_USER_INFO_0 = _WKSTA_USER_INFO_0;

WKSTA_USER_INFO_1 = _WKSTA_USER_INFO_1;

//Declaration of the Function

//Notice the Var clause in front of the pointer.

//This means that this is a returning parameter

//in addition to the Function Result.

Function NetWkstaUserEnum(ServerName : lpWStr;

Level : DWord;

Var Buffer : Pointer;

PrefMaxLen : DWord;

Const EntriesRead,

TotalEntries,

Resume_Handle : lpDWord) : LongInt; StdCall; External 'NETAPI32.DLL';

Function NetApiBufferAllocate(ByteCount : DWord; Buffer : Pointer) : LongInt; StdCall; External 'NETAPI32.DLL';

Function NetApiBufferFree(Buffer : Pointer) : LongInt; StdCall; External 'NETAPI32.DLL';

Type

TForm1 = Class(TForm)

Button1: TButton;

Edit1: TEdit;

Label1: TLabel;

Memo1: TMemo;

procedure Button1Click(Sender: TObject);

Private

Public

//This is useful later to stear our program according to the system versions.

Function ReturnSystemVersion : DWord;

End;

Var

Form1: TForm1;

Buffer : Pointer;

ServerName : Array[0..255] Of Char;

EntriesRead,

TotalEntries,

Resume_Handle : DWord;

NET_API_STATUS : LongInt;

WKSTA_STRUCT_0 : WKSTA_USER_INFO_0;

WKSTA_STRUCT_1 : WKSTA_USER_INFO_1;

Implementation

{$R *.DFM}

//And ofcoarse ... we need som code inside it ... :o)

Function TForm1.ReturnSystemVersion : DWord;

Begin

Result := Win32PlatForm;

End;

Procedure TForm1.Button1Click(Sender: TObject);

Var

I : Integer;

Begin

//We make a case loop to control what we will do.

//Since I'm not familiar with other than NT programming,

//I'll show you an NT example.

Case ReturnSystemVersion Of

VER_PLATFORM_WIN32s : Begin //System is Win32s

End;

VER_PLATFORM_WIN32_WINDOWS : Begin //System is Win95

End;

VER_PLATFORM_WIN32_NT : Begin //System is WinNT

Memo1.Lines.Clear;

StringToWideChar(Edit1.Text,@ServerName,256); //Convert the string to UNICode VERY IMPORTANT !

Resume_Handle := 0; //This must be 0 in the first call.

NET_API_STATUS := NetWkstaUserEnum(@ServerName,0,Buffer,SizeOf(WKSTA_USER_INFO_0),@EntriesRead,@TotalEntries,@Resume_Handle);

If NET_API_STATUS = 0 Then //We don' want to do this if an error occurs, otherwise we get a nasty error message.

Begin

//Remember to select the CORRECT structure according to your level.

WKSTA_STRUCT_0 := WKSTA_USER_INFO_0(Buffer^); //This syntax returns an error if you execute it with an NET_API_STATUS > 0.

//And now if youre member of the administrator account ... just watch the wonderful result og API programming.... :o)

For I := 0 To EntriesRead - 1 Do Memo1.Lines.Add(WideCharToSTring(WKSTA_STRUCT_0.User_Name)); //Remember to convert from UNICode to String.

//Good luck ... and pls. mail me if you have firther questions... ;o)

End

Else

ShowMessage(SysErrorMessage(NET_API_STATUS));

End;

End;

End;

End.

*** CODE END ***

caiu como uma luva, me retorna tanto o nome da máquina como o usuário, agora, você me disse em outra oportunidade que só poderia ser executado pelo Administrador, ainda continua sua afirmação? porque se sim, volto a estaca zero;

Link para o comentário
Compartilhar em outros sites

  • 0

opa

caiu como uma luva, me retorna tanto o nome da máquina como o usuário, agora, você me disse em outra oportunidade que só poderia ser executado pelo Administrador, ainda continua sua afirmação? porque se sim, volto a estaca zero;
Seus problemas acabaram!! asuhsuha

você pode usar esta rotina pra detectar se o usuário

é Admin no Windows...

retirada do código fonte do Inno setup rs

Function isAdmin: Boolean;
const
  DOMAIN_ALIAS_RID_ADMINS = $00000220;

function IsMemberOfGroup(const DomainAliasRid: DWORD): Boolean;
const
  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
    (Value: (0, 0, 0, 0, 0, 5));
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  SE_GROUP_ENABLED           = $00000004;
  SE_GROUP_USE_FOR_DENY_ONLY = $00000010;
var
  Sid: PSID;
  CheckTokenMembership: function(TokenHandle: THandle; SidToCheck: PSID;
    var IsMember: BOOL): BOOL; stdcall;
  IsMember: BOOL;
  Token: THandle;
  GroupInfoSize: DWORD;
  GroupInfo: PTokenGroups;
  I: Integer;
begin
  if Win32Platform <> VER_PLATFORM_WIN32_NT then begin
    Result := True;
    Exit;
  end;

  Result := False;

  if not AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
     SECURITY_BUILTIN_DOMAIN_RID, DomainAliasRid,
     0, 0, 0, 0, 0, 0, Sid) then
    Exit;
  try
    { Use CheckTokenMembership if available. MSDN states:
      "The CheckTokenMembership function should be used with Windows 2000 and
      later to determine whether a specified SID is present and enabled in an
      access token. This function eliminates potential misinterpretations of
      the active group membership if changes to access tokens are made in
      future releases." }
    CheckTokenMembership := nil;
    if Lo(GetVersion) >= 5 then
      CheckTokenMembership := GetProcAddress(GetModuleHandle(advapi32),
        'CheckTokenMembership');
    if Assigned(CheckTokenMembership) then begin
      if CheckTokenMembership(0, Sid, IsMember) then
        Result := IsMember;
    end
    else begin
      GroupInfo := nil;
      if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,Token) then begin
        if GetLastError <> ERROR_NO_TOKEN then
          Exit;
        if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token) then
          Exit;
      end;
      try
        GroupInfoSize := 0;
        if not GetTokenInformation(Token, TokenGroups, nil, 0, GroupInfoSize) and
           (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
          Exit;

        GetMem(GroupInfo, GroupInfoSize);
        if not GetTokenInformation(Token, TokenGroups, GroupInfo,
           GroupInfoSize, GroupInfoSize) then
          Exit;

        for I := 0 to GroupInfo.GroupCount-1 do begin
          if EqualSid(Sid, GroupInfo.Groups[I].Sid) and
             (GroupInfo.Groups[I].Attributes and (SE_GROUP_ENABLED or
              SE_GROUP_USE_FOR_DENY_ONLY) = SE_GROUP_ENABLED) then begin
            Result := True;
            Break;
          end;
        end;
      finally
        FreeMem(GroupInfo);
        CloseHandle(Token);
      end;
    end;
  finally
    FreeSid(Sid);
  end;
end;

begin
  Result := IsMemberOfGroup(DOMAIN_ALIAS_RID_ADMINS);
end;

pra usar

if isAdmin then

é admin else

não é;

lembrando que só a partir do windows 2000 existe isso de Administrador,

pra windows 9x/ME sempre vai retornar true...

abraço

Link para o comentário
Compartilhar em outros sites

  • 0
o código do Torry's não funcionou
Que pena, mas o que não funcionou?

...

caiu como uma luva, me retorna tanto o nome da máquina como o usuário, agora, você me disse em outra oportunidade que só poderia ser executado pelo Administrador, ainda continua sua afirmação? porque se sim, volto a estaca zero;

Como você continua utilizando a função NetWkstaUserEnum (também no exemplo do Torry's), vale o que está lá no remarks do msdn (dá uma olhada naquele link que postei):

Windows 2000: If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the access control list (ACL) for the securable object.

Windows NT: Only members of the Administrators local group can successfully execute NetWkstaUserEnum function both locally and on a remote server.

só por esses dois comentários, é possível ver que há a possibilidade de você não obter o resultado da função.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Fiquei triste,

se vou colocar essa rotina em um programa, não posso exigir que todos que se loguem sejam usuários Administradores para usarem esse programa, já que quem não for não terá listado os usuários de outros computadores para poder se comunicarem; será que não tem outra maneira?

e agora pouco fiz um teste, tenho 2 pcs aqui, mesmo estando conectado como adminstrador nas duas máquinas em uma consegui listar o nome do pc e o usuário da outra, mas, quando fiz o contrário, deu uma mensagem "Acesso Negado", porque? Já desabilitei firewall e tudo!!!!

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,2k
    • Posts
      651,9k
×
×
  • Criar Novo...