Rede - listando a rede WNetOpenEnum API |
Top Previous Next |
|
unit fmMain;
//****************************************************************************** // Walk over network // WNetOpenEnum example // // (c) 2000, Alexey Dynnikov <aldyn@aldyn.ru> // http://www.aldyn.ru/ // Delphi components, examples and articles: services, performance, security... // // Feel free to use any or all source code, provided you retain the // credit under my name. //******************************************************************************
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls;
type TMainForm = class(TForm) TV: TTreeView; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end;
var MainForm: TMainForm;
implementation
{$R *.DFM}
const InitialSize = $1; // Any positive value is acceptable.
type TNetEnumThread = class(TThread) ChildNode: String; TreeNode: TTreeNode; procedure AddChildNode; procedure Execute; override; procedure LoadNetNode(NetNode: PNetResourceA); end;
procedure TNetEnumThread.Execute; begin TreeNode:=nil; LoadNetNode(nil); end;
procedure TNetEnumThread.AddChildNode; begin TreeNode:=MainForm.TV.Items.AddChild(TreeNode,ChildNode); end;
procedure TNetEnumThread.LoadNetNode(NetNode: PNetResourceA); var hEnum : THandle; Count,BufSize, Usage: DWORD; NR,Buf: PNetResourceA; R: Integer; CurrentNode: TTreeNode; begin R:=WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,0{RESOURCEUSAGE_CONTAINER},NetNode,hEnum); if R <> NO_ERROR then exit;
BufSize:=InitialSize; GetMem(Buf,BufSize); try while True do begin Count:=$FFFFFFFF; // I wish to read ALL items R:=WNetEnumResource(hEnum,Count, Buf, BufSize);
if R = ERROR_MORE_DATA then // Oops ! The InitialSize is too small ! begin Count:=$FFFFFFFF; // I wish to read ALL items FreeMem(Buf); GetMem(Buf,BufSize); R:=WNetEnumResource(hEnum,Count, Buf, BufSize); end;
if R = ERROR_NO_MORE_ITEMS then Break; // All items are processed if R <> NO_ERROR then Abort; // R is the error code. Process it!
NR:=Buf; while Count > 0 do begin CurrentNode:=TreeNode; // Remember current position
if NR.lpRemoteName <> nil then ChildNode:=StrPas(NR.lpRemoteName) else ChildNode:='';
// Gather node information and display it in textual form ChildNode:=ChildNode+' DisplayType='; case NR.dwDisplayType of RESOURCEDISPLAYTYPE_DOMAIN: ChildNode:=ChildNode+'Domain'; RESOURCEDISPLAYTYPE_GENERIC: ChildNode:=ChildNode+'Generic'; RESOURCEDISPLAYTYPE_SERVER: ChildNode:=ChildNode+'Server'; RESOURCEDISPLAYTYPE_SHARE: ChildNode:=ChildNode+'Share'; RESOURCEDISPLAYTYPE_GROUP: ChildNode:=ChildNode+'Group'; RESOURCEDISPLAYTYPE_NETWORK: ChildNode:=ChildNode+'Network'; RESOURCEDISPLAYTYPE_ROOT: ChildNode:=ChildNode+'Root'; RESOURCEDISPLAYTYPE_SHAREADMIN: ChildNode:=ChildNode+'ShareAdmin'; RESOURCEDISPLAYTYPE_DIRECTORY: ChildNode:=ChildNode+'Directory'; RESOURCEDISPLAYTYPE_TREE: ChildNode:=ChildNode+'Tree'; RESOURCEDISPLAYTYPE_NDSCONTAINER: ChildNode:=ChildNode+'NDS Container'; else ChildNode:=ChildNode+'? ('+IntToStr(NR.dwDisplayType)+')'; end;
if NR.dwScope = RESOURCE_GLOBALNET then // dwUsage member is usable in this case only begin ChildNode:=ChildNode+' Usage=';
Usage:=NR.dwUsage; if (Usage and RESOURCEUSAGE_CONNECTABLE) <> 0 then ChildNode:=ChildNode+'Connectable;'; Usage:=Usage and not RESOURCEUSAGE_CONNECTABLE;
if (Usage and RESOURCEUSAGE_CONTAINER) <> 0 then ChildNode:=ChildNode+'Container;'; Usage:=Usage and not RESOURCEUSAGE_CONTAINER;
if (Usage and RESOURCEUSAGE_NOLOCALDEVICE) <> 0 then ChildNode:=ChildNode+'NoLocalDevice'; Usage:=Usage and not RESOURCEUSAGE_NOLOCALDEVICE;
if (Usage and RESOURCEUSAGE_SIBLING) <> 0 then ChildNode:=ChildNode+'Sibling'; Usage:=Usage and not RESOURCEUSAGE_SIBLING;
if (Usage and RESOURCEUSAGE_ATTACHED) <> 0 then ChildNode:=ChildNode+'Attached'; Usage:=Usage and not RESOURCEUSAGE_ATTACHED;
if (Usage and RESOURCEUSAGE_RESERVED) <> 0 then ChildNode:=ChildNode+'Reserved'; Usage:=Usage and not RESOURCEUSAGE_RESERVED;
if Usage <> 0 then ChildNode:=ChildNode+'? ('+IntToHex(Usage,8)+')'; end;
// Check for dwType value ChildNode:=ChildNode+' Type='; case NR.dwType of RESOURCETYPE_ANY: ChildNode:=ChildNode+'Any'; RESOURCETYPE_DISK: ChildNode:=ChildNode+'Disk'; RESOURCETYPE_PRINT: ChildNode:=ChildNode+'Print'; else ChildNode:=ChildNode+'?'; end;
// Analyze dwScope member ChildNode:=ChildNode+' Scope='; case NR.dwScope of RESOURCE_CONNECTED: ChildNode:=ChildNode+'Connected'; RESOURCE_GLOBALNET: ChildNode:=ChildNode+'Globalnet'; RESOURCE_REMEMBERED: ChildNode:=ChildNode+'Remembered'; else ChildNode:=ChildNode+'?'; end;
// Add new node to the tree view - and do it in the main thread Synchronize(AddChildNode);
// Process subnodes LoadNetNode(NR);
TreeNode:=CurrentNode; // restore current position // after modification
// Go to the next record INC(NR); DEC(Count); end; end; finally WNetCloseEnum(hEnum); // Close handle FreeMem(Buf); // Free memory1 end; end;
procedure TMainForm.FormCreate(Sender: TObject); begin TNetEnumThread.Create(False); end;
end. |