#include "FormMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "FtpSrv"
#pragma link "Ftpcli"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// Rebrowse:
void __fastcall TForm1::ButtonOKClick(TObject *Sender)
{
DoEnumeration();
}
//---------------------------------------------------------------------------
// Allow loading of tree view from a file:
void __fastcall TForm1::mniLoadFromFileClick(TObject *Sender)
{
if ( OpenDialog->Execute())
tvResources->LoadFromFile(OpenDialog->FileName);
}
//---------------------------------------------------------------------------
// Allow saving of tree view to a file:
void __fastcall TForm1::mniSaveToFileClick(TObject *Sender)
{
if ( SaveDialog->Execute())
tvResources->SaveToFile(SaveDialog->FileName);
}
//---------------------------------------------------------------------------
// Collapse all containers in the tree view:
void __fastcall TForm1::mniCollapseAllClick(TObject *Sender)
{
tvResources->FullCollapse();
}
//---------------------------------------------------------------------------
// Expand all containers in the tree view:
void __fastcall TForm1::mniExpandAllClick(TObject *Sender)
{
tvResources->FullExpand();
}
//---------------------------------------------------------------------------
// Add a connection to the tree view.
// Mostly used for persistent and currently connected
// resources to be displayed.
void __fastcall TForm1::AddConnection(NETRESOURCE* NetRes)
{
AnsiString ItemName;
ItemName=Trim(AnsiString(NetRes->lpLocalName));
if ( Trim(AnsiString(NetRes->lpRemoteName))!= "" )
{
if ( ItemName != "" ) ItemName += " ";
ItemName += "-> "+Trim(AnsiString(NetRes->lpRemoteName));
}
tvResources->Items->Add(tvResources->Selected,ItemName);
}
//---------------------------------------------------------------------------
// Add child item to container denoted as current top;
// this just adds a string for purposes such as being unable
// to enumerate a container. That is, the container's shares
// are not accessible to us.
void __fastcall TForm1::AddShareString(int TopContainerIndex, AnsiString ItemName)
{
tvResources->Items->AddChild(tvResources->Items->Item[TopContainerIndex],ItemName);
}
//---------------------------------------------------------------------------
// Add child item to container denoted as current top:
void __fastcall TForm1::AddShare(int TopContainerIndex, NETRESOURCE* NetRes)
{
AnsiString ItemName;
ItemName = Trim(AnsiString(NetRes->lpRemoteName));
if ( Trim(AnsiString(NetRes->lpComment)) != "")
{
if (ItemName!="") ItemName += " ";
ItemName += "("+AnsiString(NetRes->lpComment)+")";
}
tvResources->Items->AddChild(tvResources->Items->Item[TopContainerIndex],ItemName);
}
//---------------------------------------------------------------------------
// Add item to tree view; indicate that it is a container:
void __fastcall TForm1::AddContainer(NETRESOURCE* NetRes)
{
switch (grpListType->ItemIndex)
{
// Connected resources
case 0: ListType = RESOURCE_CONNECTED; break;
// Persistent resources
case 1: ListType = RESOURCE_REMEMBERED; break;
// Global
case 2: ListType = RESOURCE_GLOBALNET; break;
}
switch (grpResourceType->ItemIndex)
{
// Disk resources
case 0: ResourceType = RESOURCETYPE_DISK; break;
// Print resources
case 1: ResourceType = RESOURCETYPE_PRINT; break;
// All
case 2: ResourceType = RESOURCETYPE_ANY; break;
}
Screen->Cursor = crHourGlass;
try
{
// Delete any old items in the tree view
for (Loop = tvResources->Items->Count-1;Loop > 0;Loop-- )
tvResources->Items->Item[Loop]->Delete();
}
catch(...)
{ return; }
// Start enumeration:
r = WNetOpenEnum(ListType,ResourceType,0,NULL,&hEnum);
if ( r != NO_ERROR)
{
if ( r == ERROR_EXTENDED_ERROR )
MessageDlg("Unable to Enumerate the Network.\nA network-specific error occurred.",
mtError,TMsgDlgButtons() << mbOK,0);
else
MessageDlg("Unable to Enumerate the Network.",
mtError,TMsgDlgButtons() << mbOK,0);
return;
};
try
{
// We got a valid enumeration handle; walk the resources:
for(;;)
{
EntryCount = 1;
NetResLen = sizeof(NetRes);
r = WNetEnumResource(hEnum,&EntryCount,NetRes,&NetResLen);
switch (r)
{
case 0:
// It's a container, iterate it:
if ( NetRes[0]->dwUsage == RESOURCEUSAGE_CONTAINER )
DoEnumerationContainer(NetRes[0]);
// Persistent and connected resources show up here:
else if ( ListType >= RESOURCE_REMEMBERED && ListType <= RESOURCE_CONNECTED )
AddConnection(NetRes[0]);
break;
// Done
case ERROR_NO_MORE_ITEMS:
return;
//Other error
default :
MessageDlg("Error Walking Resources.",mtError,TMsgDlgButtons() << mbOK,0);
return;
}
}
}
__finally
{
Screen->Cursor=crDefault;
// Close enumeration handle:
WNetCloseEnum(hEnum);
}
}
//---------------------------------------------------------------------------
// Enumerate through the specified container:
// This function is usually recursively called.
void __fastcall TForm1::DoEnumerationContainer(NETRESOURCE* NetResContainer)
{
NETRESOURCE* NetRes[11] ;
int TopContainerIndex ;
DWORD r, EntryCount, NetResLen;
HANDLE hEnum;
// Add container name to tree view:
AddContainer(NetResContainer);
// Keep track of this item as current root:
TopContainerIndex = tvResources->Items->Count-1;
// Start enumeration:
if ( ListType == RESOURCE_GLOBALNET )
// Enumerating global net:
r = WNetOpenEnum(ListType,ResourceType,RESOURCEUSAGE_CONTAINER,
NetResContainer,&hEnum);
else
// Enumerating connections or persistent (won't normally get here):
r = WNetOpenEnum(ListType,ResourceType,RESOURCEUSAGE_CONTAINER,
NULL,&hEnum);
// Couldn't enumerate through this container; just make a note
// of it and continue on:
if ( r != NO_ERROR )
{
AddShareString(TopContainerIndex,"<Couldn''t Enumerate Resources(Error #"+
IntToStr(r)+">");
WNetCloseEnum(hEnum);
return;
}
try
{
// We got a valid enumeration handle; walk the resources:
for (;;)
{
EntryCount = 1;
NetResLen = sizeof(NetRes);
r = WNetEnumResource(hEnum,&EntryCount,NetRes,&NetResLen);
switch (r)
{
case 0:
// Yet another container to enumerate; call this function
// recursively to handle it:
if ((NetRes[0]->dwUsage == RESOURCEUSAGE_CONTAINER) ||
(NetRes[0]->dwUsage == 10))
DoEnumerationContainer(NetRes[0]);
else
switch (NetRes[0]->dwDisplayType)
{
// Top level type:
case RESOURCEDISPLAYTYPE_GENERIC:
case RESOURCEDISPLAYTYPE_DOMAIN:
case RESOURCEDISPLAYTYPE_SERVER:
AddContainer(NetRes[0]);
break;
// Share:
case RESOURCEDISPLAYTYPE_SHARE:
AddShare(TopContainerIndex,NetRes[0]);
break;
}
break;