NetShareEnum in delphi

Im trying to list all shares on a REMOTE machine (this includes hidden shares such as c$), can someone please advise me on how to do this in full-working code?
robbiegroveAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ivanov_GCommented:
I think NetShareEnum is wrong starting point. You need WNetEnumResource for network shares

http://www.delphiworld.narod.ru/base/enum_net_connections.html
0
robbiegroveAuthor Commented:
im 90% sure WNetEnumResource is for LOCAL shares..
I have used NetShareEnum in C before and it IS what iam after, however i had alot of trouble trying to port it to delphi.
0
Russell LibbySoftware Engineer, Advisory Commented:
Just to clarify:

1.) NetShareEnum is not the wrong starting point; it can return hidden shares where WNetEnumResource cant.
2.) WNetEnumResource CAN be used to get remote resource location; it just can't get the hidden shares.

Here is an msdn example translated to delphi, just compile it as a console app, run it, and enter the server name. note: PLEASE make sure you have permissions to the server before saying it does not work.

Regards,
Russell

----

program netenum;
{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils,
  Classes;

type
  _SHARE_INFO_502         =  packed record
     shi502_netname:      PWideChar;
     shi502_type:         DWORD;
     shi502_remark:       PWideChar;
     shi502_permissions:  DWORD;
     shi502_max_uses:     DWORD;
     shi502_current_uses: DWORD;
     shi502_path:         LPWSTR;
     shi502_passwd:       LPWSTR;
     shi502_reserved:     DWORD;
     shi502_security_dsc: PSECURITY_DESCRIPTOR;
  end;
  SHARE_INFO_502          =  _SHARE_INFO_502;
  PSHARE_INFO_502         =  ^SHARE_INFO_502;
  LPSHARE_INFO_502        =  PSHARE_INFO_502;
  TShareInfo502           =  SHARE_INFO_502;
  PShareInfo502           =  PSHARE_INFO_502;

type
  TShareInfo502Array      =  Array [0..MaxWord] of TShareInfo502;
  PShareInfo502Array      =  ^TShareInfo502Array;

function   NetApiBufferFree(buffer: Pointer): DWORD; stdcall; external 'netapi32.dll';
function   NetShareEnum(servername: PWideChar;
                        level: DWORD;
                        bufptr: PByteArray;
                        prefmaxlen: DWORD;
                        entriesread: PDWORD;
                        totalentries: PDWORD;
                        resume_handle: PDWORD): DWORD; stdcall; external 'netapi32.dll';


var
  p:             PShareInfo502Array;
  res,
  er, tr,
  resume,
  i:             DWORD;
  szServer:      String;
  lpwszServer:   Array [0..255] of WideChar;
  pwszServer:    PWideChar;

begin

   er:=0;
   tr:=0;
   resume:=0;

   // Flush input on console
   FlushConsoleInputBuffer(GetStdhandle(STD_INPUT_HANDLE));

   // Get the server
   Write('Enter server name: ');
   ReadLn(szServer);

   // Check parameter
   if (Length(szServer) = 0) then
     pwszServer:=nil
   else
   begin
     // Make sure the server starts with a \\
     if (Pos('\\', szServer) <> 1) then szServer:='\\'+szServer;
     StringToWideChar(szServer, @lpwszServer, SizeOf(lpwszServer));
     pwszServer:=@lpwszServer;
   end;

   // Print a report header.
   WriteLn('Share:              Local Path:                   Uses:   Descriptor:');
   WriteLn('---------------------------------------------------------------------');

   // Call the NetShareEnum function; specify level 502.
   repeat
     res:=NetShareEnum(pwszServer, 502, @p, DWORD(-1), @er, @tr, @resume);
     // If the call succeeds
     if (res = ERROR_SUCCESS) or (res = ERROR_MORE_DATA) then
     begin
        // Loop through the entries;
        // print retrieved data.
        for i:=1 to Pred(er) do
        begin
           Write(Format('%-20s%-30s%-0.8d', [WideCharToString(p^[i].shi502_netname),
                   WideCharToString(p^[i].shi502_path), p^[i].shi502_current_uses]));
           //
           //  Validate the value of the
           //  shi502_security_descriptor member.
           //
           if IsValidSecurityDescriptor(p^[i].shi502_security_dsc) then
               WriteLn('Yes')
            else
               WriteLn('No');
        end;
        //
        // Free the allocated buffer.
        //
        NetApiBufferFree(p);
     end
     else
         WriteLn('Error: ', res);

     // Continue to call NetShareEnum while
     //  there are more entries.

   until (res <> ERROR_MORE_DATA);

   // Pause
   ReadLn;

end.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

Wim ten BrinkSelf-employed developerCommented:
program WMI;

{$APPTYPE CONSOLE}

uses Windows, SysUtils, Classes, ActiveX, Variants, 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(OleProperty).QueryInterface(riid, ppObject));
  except
    Result := False;
    IUnknown(ppObject) := nil;
  end;
end;

procedure RunMe;
const
  sQuery = 'select * from Win32_Share';
var
  Enum: IEnumVariant;
  Item: SWbemObject;
  Lines: TStringList;
  Locator: SWbemLocator;
  MachineName: string;
  ObjectSet: SWbemObjectSet;
  Prop: SWbemProperty;
  PropEnum: IEnumVariant;
  Services: SWbemServices;
begin
  Lines := TStringList.Create;
  MachineName := 'Knight'; // Name of machine that needs to be enumerated.
  try
    Locator := CoSWbemLocator.Create;
    Services := Locator.ConnectServer(MachineName, 'root\cimv2', '', '', '', '', 0, nil);
    ObjectSet := Services.ExecQuery(sQuery, 'WQL', wbemFlagBidirectional, nil);
    Enum := ObjectSet._NewEnum as IEnumVariant;
    while NextItem(Enum, SWBemObject, Item) do begin
      Lines.Add(Item.Path_.Path);
      PropEnum := Item.Properties_._NewEnum as IEnumVariant;
      while NextItem(PropEnum, SWBemProperty, Prop) do begin
        Lines.Add(Format('+ %s: %s = %s', [Prop.Name, VarTypeAsText(VarType(Prop.Get_Value)), Trim(VarToStrDef(Prop.Get_Value, '<Error>'))]));
      end;
      Lines.Add('');
    end;
  except on E: Exception do Lines.Add(E.Message);
  end;
  Write(Lines.Text);
  Lines.Free;
end;

begin
  if Assigned(InitProc) then TProcedure(InitProc);
  RunMe;
  Write('Press <Enter> to quit');
  ReadLn;
end.

See http://www.workshop-alex.org/Sources/WbemScripting_TLB/WbemScripting_TLB.html or http://www.workshop-alex.org/Sources/WbemScripting_TLB/WbemScripting_TLB.pas for the WMI unit used in above code. This version is optimized for Delphi 7.

Yeah, well. I'm using WMI to access the share information, which is the easiest way to enumerate shares on a REMOTE system. All you need to provide is the right machine name, which in my case is "Knight".
Since this is a console application, I needed to initialize the COM system by calling InitProc. The use of WMI can be a lot easier than the use of some obscure API functions. ;-)
0
robbiegroveAuthor Commented:
Thanks rllibby helped ALOT! almost exactly what i was looking for :D

Sorry Workshop_alex, just wanted to know how to use NetShareEnum in delphi.
Probably should have made that more clear.. Is there a way i can accept your answer aswell tho?
0
Wim ten BrinkSelf-employed developerCommented:
Don't worry, robbie... I just added my answer to show there are some other ways to get information too. Many people are afraid to use WMI in the first place since they think it's complex... Well, they are right of course but hey, if you learn fast you'll learn to use it fast too. :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.