unit Unit1;
interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ShlObj, Buttons;

//необходимые константы
const
  LM20_NNLEN = 12;
  SHPWLEN = 8;
  SHI50F_RDONLY = 1;
  SHI50F_FULL = 2;
  STYPE_DISKTREE = 0;

  MaxNetArrayItems=512;

//формируем тип для записи с необходимыми параметрами
type
//для Win'9x
  TShareInfo50 = packed record
    shi50_netname: array[0..LM20_NNLEN] of Char; //сетевое имя
    shi50_type: Byte;                            //тип ресурса
    shi50_flags: Short;                          //флаг доступа
    shi50_remark: PChar;                         // комментарий
    shi50_path: PChar;                           // путь к ресурсу
    shi50_rw_password: array[0..SHPWLEN] of Char;//пароль полного доступа
    shi50_ro_password: array[0..SHPWLEN] of Char;//пароль "только чтение" доступа
  end;

TShareEvent = Record  //информация о сетевом ресурсе
Res                 :Integer;
ReadOnlyPassword    :String;
FullAccessPassword  :String;
Comments            :String;
Path                :String;
End;



  TForm1 = class(TForm)
    edComputerNetName: TEdit;
    Button1: TButton;
    ComboBox1: TComboBox;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    lbReadOnlyPassword: TLabel;
    edReadOnlyPassword: TEdit;
    lbFullAccessPassword: TLabel;
    edFullAccessPassword: TEdit;
    lbComments: TLabel;
    edComments: TEdit;
    lbPhysicalPath: TLabel;
    edPhysicalPath: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
  private
    { Private declarations }
  Procedure FillShareEnum(Items:TStrings);
  Function GetComputerNetName:String;
  Function GetShareInfo(ComputerNetName,ResourceNetName:String):TShareEvent;
  Procedure ConnectAdmin;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
Function NetShareGetInfo(const pszServer: PChar; const pszNetName: PChar;
  sLevel: SmallInt; pbBuffer: Pointer; cbBuffer: Word;
  var pcTotalAvail: Word): DWORD; stdcall; External 'svrapi.dll' name 'NetShareGetInfo';
Function NetShareEnum(const pszServer: PChar; sLevel: SmallInt;
  pbBuffer: Pointer; cbBuffer: Word; var pcEntriesRead: Word;
  var pcTotalAvail: Word): DWORD; stdcall; external 'svrapi.dll';

implementation

{$R *.DFM}

Procedure TForm1.ConnectAdmin;
Var
CompName:String;
Res:Integer;
lpNetResource:TNetResource;
ComputerName:Array[0..MAX_COMPUTERNAME_LENGTH] Of Char;
BufSize:Integer;
Begin
//получим имя локальной машины
BufSize:=MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName(@ComputerName,BufSize);
CompName:=String(ComputerName);
//если имя локальной машины совпадает с сетевым именем машины,
//значит идет запрос о сетевом ресурсе локальной машины -
//в этом случае ADMIN$ не нужен
If AnsiUpperCase(CompName)= AnsiUpperCase(edComputerNetName.Text) Then Exit;
//заполним нолями значение указателя
ZeroMemory(@lpNetResource,SizeOf(lpNetResource));
//укажем нужные значения
With lpNetResource Do
Begin
dwType:=RESOURCETYPE_ANY;
lpRemoteName:='';
lpRemoteName:=PChar('\\'+edComputerNetName.Text+'\ADMIN$'+#0);
End;
//Сезам, откройся!
Res:=WNetAddConnection3(Application.Handle,lpNetResource,Nil,Nil,CONNECT_INTERACTIVE);
//Сезам, к сожалению не открылся...
If Not(Res= NO_ERROR) Then
Begin
ShowMessage('Without connected resource ''ADMIN$'' a work impossible!');
Application.Terminate;
End;
End;

Function TForm1.GetShareInfo(ComputerNetName,ResourceNetName:String):TShareEvent;
Var
pbBuffer:^TShareInfo50;//указатель на буфер
Buf:TShareInfo50;      //сам буфер
Res:Integer;
pcTotalAvail:Word;     //количество считанных байт
Begin
With Result Do //почистим результат функции
Begin
res:=0;
ReadOnlyPassword:='';
FullAccessPassword:='';
Comments:='';
Path:='';
End;
FillChar(Buf,SizeOf(Buf),#0);//заполним буфер нолями
//ничего не укажем о нашем буфере и выполним функцию, в результате чего
//получим в переменную pcTotalAvail количество считанных байт.
NetShareGetInfo(PChar(ComputerNetName),PChar(ResourceNetName),50,Nil,0,pcTotalAvail);
//инициализируем буферный указатель и дадим ему нужное количество памяти
GetMem(pbBuffer,pcToTalAvail);
//поместим в буфер имя сетевого ресурса, зачем не знаю - имя мы уже и так
//указываем, но без этого функция почему-то не работает, по крайней мере у меня
StrPCopy(pbBuffer^.shi50_netname,ResourceNetName);
//выполним функцию еще раз уже указав параметры буфера
Res:=NetShareGetInfo(PChar(ComputerNetName),PChar(ResourceNetName),50,pbBuffer,pcTotalAvail,pcTotalAvail);
If Res = 0 Then //все в порядке
Begin
//передадим данные из указателя в "обычную" переменную
Buf:=pbBuffer^;
//заполним результат полученными значениями
Result.ReadOnlyPassword:=String(Buf.shi50_ro_password);
Result.FullAccessPassword:=String(Buf.shi50_rw_password);
Result.Comments:=String(Buf.shi50_remark);
Result.Path:=String(Buf.shi50_path);
End;
//освободим указатель
FreeMem(pbBuffer);
End;

Procedure TForm1.FillShareEnum(Items:TStrings);
Var
ShareInfo:Array[0..MaxNetArrayItems-1] Of TShareInfo50;
EntriesRead, TotalAvial:Word;
Res:Integer;
N:Integer;
Begin
Items.Clear;//почистим Items
FillChar(ShareInfo,SizeOf(ShareInfo),#0);//заполним буфер нолями
Res:=NetShareEnum(PChar('\\'+edComputerNetName.Text),50,@ShareInfo,SizeOf(ShareInfo),
EntriesRead,TotalAvial);//имя сетевой машины возьмем из строки ввода,
//предварительно озаглавив его двумя обратными слэшами
If Res = No_Error Then //функция выполнена без ошибок
For N:=0 To EntriesRead -1 Do //пройдемся по буферу считанных имен ресурсов
If Not (String(ShareInfo[N].shi50_netname)='') Then
Items.Add(String(ShareInfo[N].shi50_netname));//добавим имя машины в список
End;



Function TForm1.GetComputerNetName:String;
Var
RootItemIDList:PItemIDList;//идентификатор объекта в пространстве имен проводника
BrowseInfo:TBrowseInfo; //структура, в которой содержится информация о диалоге
Buffer:PChar; //сюда получим имя компьютера
Begin
Result:='';
//получим нужный идентификатор PItemIDList, CSIDL_NETWORK - в сетевом окружении
If Not(SHGetSpecialFolderLocation(0,CSIDL_NETWORK,RootItemIDList)=NO_ERROR)
Then Exit;
//подготовим буфер, в который получим имя компьютера
GetMem(Buffer,Max_Path);
FillChar(BrowseInfo,SizeOf(BrowseInfo),0);
//подготовим структуру TBrowseInfo
With BrowseInfo Do
Begin {With BrowseInfo}
hwndOwner:=Application.Handle;//хозяин окна - наше приложение
pidlRoot:=RootItemIDList;     //полученный ранее идентификатор
                              // объекта в списке объектов проводника
pszDisplayName:=Buffer;       //имя компьютера будем принимать в Buffer
lpszTitle:='Подключенные компьютеры'; //заголовок диалога
ulFlags:=BIF_BROWSEFORCOMPUTER;//будут показаны имена только компьютеров
End; {With BrowseInfo}

//выполним нужную функцию
If SHBrowseForFolder(BrowseInfo)=Nil Then Exit;
Result:=String(Buffer);//вот оно - сетевое имя компьютера
FreeMem(Buffer);
end;


procedure TForm1.Button1Click(Sender: TObject);
Begin
edComputerNetName.Text:=GetComputerNetName;
FillShareEnum(ComboBox1.Items);
ComboBox1.ItemIndex:=0;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
Var
ShareEvent:TShareEvent;
begin
If (edComputerNetName.Text='') Or (ComboBox1.Text='') Then
Begin
edComputerNetName.SetFocus;
Exit;
End;
ConnectAdmin;
ShareEvent:=GetShareInfo('\\'+edComputerNetName.Text,ComboBox1.Text);
edReadOnlyPassword.Text:=ShareEvent.ReadOnlyPassword;
edFullAccessPassword.Text:=ShareEvent.FullAccessPassword;
edComments.Text:=ShareEvent.Comments;
edPhysicalPath.Text:=ShareEvent.Path;
end;


procedure TForm1.BitBtn2Click(Sender: TObject);
begin
Close;
end;

end.
