NeoEvoMan
asked on
Listing thin client drives in a Windows Terminal 2003
How can I get a list of available disks/drives/files from a RDP session (Thin Client). like the list you see in Windows Explorer:
A in LapTop
C in LapTop
C in ThinClient1
C in ThinClient2
C in ThinClient3
NOTE. All those drives are listed as network drives but none API function I tried gives me that results.
A in LapTop
C in LapTop
C in ThinClient1
C in ThinClient2
C in ThinClient3
NOTE. All those drives are listed as network drives but none API function I tried gives me that results.
ASKER
Thanks for your code , but it does not work in Terminal Server 2003 (RDP session). This is the kind of problem I have experimented with some API functions that "only see" mapped network drives but not those shared in a Terminal Server session.
When a RDP session is stablished and its local resources are exposed, all the entire drives appear with next format in Windows Explorer: Drive + 'ON ' + Machine_Name, example:
A On LapTop.
C On LapTop.
Thanks
When a RDP session is stablished and its local resources are exposed, all the entire drives appear with next format in Windows Explorer: Drive + 'ON ' + Machine_Name, example:
A On LapTop.
C On LapTop.
Thanks
Another option could be the use of WMI. I'll include some example that I used in a console application:
program GetShares;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, ActiveX, WbemScripting_TLB;
function NextItem(var Enum: IEnumVARIANT; const riid: TGUID; out ppObject): Boolean;
var
OleProperty: OleVariant;
NumProp: LongWord;
begin
try
Result := Succeeded(Enum.Next(1, OleProperty, NumProp)) and (NumProp > 0) and Succeeded(IDispatch(OlePro perty).Que ryInterfac e(riid, ppObject));
except
Result := False;
IUnknown(ppObject) := nil;
end;
end;
function Prop(Obj: ISWbemObject; Name: string): string;
begin
try
Result := VarToStr(obj.Properties_.I tem(Name, 0).Get_Value);
except on E: Exception do Result := E.Message;
end;
end;
var
AFile: TextFile;
Enum: IEnumVARIANT;
Obj: ISWbemObject;
begin
if Succeeded(CoInitializeEx(n il, COINIT_MULTITHREADED or COINIT_DISABLE_OLE1DDE or COINIT_SPEED_OVER_MEMORY)) then begin
AssignFile(AFile, ChangeFileExt(ParamStr(0), '.txt'));
Rewrite(AFile);
try
Enum := CoSWbemLocator.Create.Conn ectServer( ParamStr(1 ), 'root\cimv2', '', '', '', '', 0, nil).ExecQuery('Select * from Win32_Share', 'WQL', wbemFlagBidirectional, nil)._NewEnum as IEnumVariant;
while NextItem(Enum, SWBemObject, Obj) do begin
WriteLn('Name: ', Prop(Obj, 'Name'));
WriteLn(AFile, 'Name: ', Prop(Obj, 'Name'));
WriteLn(AFile, 'Path: ', Prop(Obj, 'Path'));
WriteLn(AFile, 'Status: ', Prop(Obj, 'Status'));
WriteLn(AFile, 'Caption: ', Prop(Obj, 'Caption'));
WriteLn(AFile, 'Description: ', Prop(Obj, 'Description'));
WriteLn(AFile, 'AllowMaximum: ', Prop(Obj, 'AllowMaximum'));
WriteLn(AFile);
obj := nil;
end;
except
on E: Exception do begin
WriteLn(E.Message);
WriteLn(AFile, E.Message);
end;
end;
Enum := nil;
CoUninitialize;
CloseFile(AFile);
end;
end.
To get the unit WbemScripting_TLB all you have to do is "Project/Import type library" and add the file "C:\WINNT\system32\wbem\wb emdisp.tlb " to Delphi. If possible, don't let it create a component wrapper since it's not much use anyway. Like the other application, this is just a simple console application. Let me know if you need the WbemScripting_TLB too, or grab it from http://workshop-alex.org/Sources/WbemScripting_TLB.pas if you use Delphi 7.
I would assume that of all system environment thingies, WMI would always provide the required information. If it doesn't then I assume there's no way to retrieve the information.
program GetShares;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, ActiveX, WbemScripting_TLB;
function NextItem(var Enum: IEnumVARIANT; const riid: TGUID; out ppObject): Boolean;
var
OleProperty: OleVariant;
NumProp: LongWord;
begin
try
Result := Succeeded(Enum.Next(1, OleProperty, NumProp)) and (NumProp > 0) and Succeeded(IDispatch(OlePro
except
Result := False;
IUnknown(ppObject) := nil;
end;
end;
function Prop(Obj: ISWbemObject; Name: string): string;
begin
try
Result := VarToStr(obj.Properties_.I
except on E: Exception do Result := E.Message;
end;
end;
var
AFile: TextFile;
Enum: IEnumVARIANT;
Obj: ISWbemObject;
begin
if Succeeded(CoInitializeEx(n
AssignFile(AFile, ChangeFileExt(ParamStr(0),
Rewrite(AFile);
try
Enum := CoSWbemLocator.Create.Conn
while NextItem(Enum, SWBemObject, Obj) do begin
WriteLn('Name: ', Prop(Obj, 'Name'));
WriteLn(AFile, 'Name: ', Prop(Obj, 'Name'));
WriteLn(AFile, 'Path: ', Prop(Obj, 'Path'));
WriteLn(AFile, 'Status: ', Prop(Obj, 'Status'));
WriteLn(AFile, 'Caption: ', Prop(Obj, 'Caption'));
WriteLn(AFile, 'Description: ', Prop(Obj, 'Description'));
WriteLn(AFile, 'AllowMaximum: ', Prop(Obj, 'AllowMaximum'));
WriteLn(AFile);
obj := nil;
end;
except
on E: Exception do begin
WriteLn(E.Message);
WriteLn(AFile, E.Message);
end;
end;
Enum := nil;
CoUninitialize;
CloseFile(AFile);
end;
end.
To get the unit WbemScripting_TLB all you have to do is "Project/Import type library" and add the file "C:\WINNT\system32\wbem\wb
I would assume that of all system environment thingies, WMI would always provide the required information. If it doesn't then I assume there's no way to retrieve the information.
ASKER
Workshop_Alex,
Thanks for taking a time to try to help me with this question and I would like to tell you that it works because your effort but unfortunately again it didn't work.
Regards
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
program GetNetShares;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
const
NERR_Success = 0; // Success
type
NET_API_STATUS = DWORD;
PShare_Info_0 = ^TShare_Info_0;
TShare_Info_0 = record
shi0_netname: PWideChar;
end;
PShare_Info_0_Arr = ^TShare_Info_0_Arr;
TShare_Info_0_Arr = array[0..MaxInt div SizeOf(TShare_Info_0) - 1] of TShare_Info_0;
PShare_Info_1 = ^TShare_Info_1;
TShare_Info_1 = record
shi1_netname: PWideChar;
shi1_type: DWORD;
shi1_remark: PWideChar;
end;
PShare_Info_1_Arr = ^TShare_Info_1_Arr;
TShare_Info_1_Arr = array[0..MaxInt div SizeOf(TShare_Info_1) - 1] of TShare_Info_1;
PShare_Info_2 = ^TShare_Info_2;
TShare_Info_2 = record
shi2_netname: PWideChar;
shi2_type: DWORD;
shi2_remark: PWideChar;
shi2_permissions: DWORD;
shi2_max_uses: DWORD;
shi2_current_uses: DWORD;
shi2_path: PWideChar;
shi2_passwd: PWideChar;
end;
PShare_Info_2_Arr = ^TShare_Info_2_Arr;
TShare_Info_2_Arr = array[0..MaxInt div SizeOf(TShare_Info_2) - 1] of TShare_Info_2;
PShare_Info_502 = ^TShare_Info_502;
TShare_Info_502 = record
shi502_netname: PWideChar;
shi502_type: DWORD;
shi502_remark: PWideChar;
shi502_permissions: DWORD;
shi502_max_uses: DWORD;
shi502_current_uses: DWORD;
shi502_path: PWideChar;
shi502_passwd: PWideChar;
shi502_reserved: DWORD;
shi502_security_descriptor
end;
PShare_Info_1004 = ^TShare_Info_1004;
TShare_Info_1004 = record
shi1004_remark: PWideChar;
end;
PShare_Info_1006 = ^TShare_Info_1006;
TShare_Info_1006 = record
shi1006_max_uses: DWORD;
end;
PShare_Info_1501 = ^TShare_Info_1501;
TShare_Info_1501 = record
shi1501_reserved: DWORD;
shi1501_security_descripto
end;
function NetShareEnum(servername: PWideChar; level: DWORD; var buf: Pointer; prefmaxlen: DWORD; var entriesread: DWORD; var totalentries: DWORD; var resume_handle: DWORD): NET_API_STATUS; stdcall; external 'netapi32.dll';
function NetShareGetInfo(servername
function NetApiBufferFree(P: Pointer): NET_API_STATUS; stdcall; external 'netapi32.dll';
var
Server: PWideChar;
Buffer, Loop: PShare_Info_0;
Buf502: PShare_Info_502;
NetResult: DWORD;
entriesread: DWORD;
totalentries: DWORD;
resume_handle: DWORD;
I: Integer;
begin
if (ParamCount = 0) then begin
Server := nil;
end
else begin
Server := PWideChar(WideString(Param
end;
entriesread := 0;
totalentries := 0;
resume_handle := 0;
NetResult := NetShareEnum(Server, 0, Pointer(Buffer), DWORD(-1), entriesread, totalentries, resume_handle);
if (NetResult = NERR_Success) then begin
Loop := Buffer;
WriteLn('Entries read: ', entriesread);
for I := 1 to entriesread do begin
WriteLn('Name: ', string(Loop.shi0_netname))
try
NetResult := NetShareGetInfo(Server, Loop.shi0_netname, 502, Pointer(Buf502));
if (NetResult = NERR_Success) then begin
WriteLn('* Net name: ', string(Buf502.shi502_netna
WriteLn('* Type: ', Buf502.shi502_type);
WriteLn('* Remark: ', string(Buf502.shi502_remar
WriteLn('* Permissions: ', Buf502.shi502_permissions)
WriteLn('* Max uses: ', Buf502.shi502_max_uses);
WriteLn('* Current uses: ', Buf502.shi502_current_uses
WriteLn('* Path: ', string(Buf502.shi502_path)
WriteLn('* Password: ', string(Buf502.shi502_passw
WriteLn('* Reserved: ', Buf502.shi502_reserved);
end
else begin
WriteLn('* Error: ', SysErrorMessage(NetResult)
end;
NetApiBufferFree(Buf502);
except on E: Exception do WriteLn('* Error: ', E.Message);
end;
WriteLn;
Inc(Loop);
end;
NetApiBufferFree(Buffer);
end;
end.
Basically, the only thing you need to know is the Path for all disk resources. It should work, technicakky speaking.