Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 618
  • Last Modified:

Getting server name/time

I have function that gets the time from the server using net from the command line. I would like something that works in Windows 95 and NT, in NT it seems one can use NetRemoteTOD/Timeserv in the resource kit, should I implement this if NT is running or should I stick with net?

Anyone, the function used to work, but in porting to 32-bit I have now a problem getting the server name, my code is as follows:

function GetServerName(var serverName: string): boolean;
var
   x: integer;
   fullNetPath, driveLetter: string;
   slstDrives: TStringList;
   returnValue: word;
   i: integer;

   function TrimNetPath: string;
   var
     lengthStringToTrim: word;
     i : integer;
     nextChar, netPathToTrim: string;
   begin
      { the fully qualified network path is in the form
        \\serverName\networkPath (stored in fullNetPath)
        this function returns the server name }
      netPathToTrim := fullNetPath;
      lengthStringToTrim := Length(netPathToTrim);
      i := 3;
      Result := '\\';
      nextChar := Copy(netPathToTrim, i, 1);
      while ((nextChar <> '\') and (i <= lengthStringToTrim)) do begin
         Result := Result + nextChar;
         Inc(i);
         nextChar := Copy(netPathToTrim, i, 1)
      end;
   end;
begin
   { initialize variables }
   x := 256;

   { get DRIVE_REMOTE letters }
   slstDrives := TStringList.Create;
   try
      // other function of mine that returns remote drive letters
      GetDriveLettersForDriveType([DRIVE_REMOTE], slstDrives);
      i := -1;
      if slstDrives.Count > 0 then
         repeat
            inc(i);
            { get fully qualified network path - API call }
            driveLetter := Format('%s:', [Copy(slstDrives.Strings[i], 1, 1)]);
            returnValue := WNetGetconnection(PChar(driveLetter), PChar(fullNetPath), x);
         until ((returnValue = WN_SUCCESS) or (i = slstDrives.Count - 1));
   finally
      slstDrives.Free;
   end;

   Result := (returnValue = WN_SUCCESS);
   if result then
      serverName := TrimNetPath
   else
      serverName := '';
end;

The problem is with WNetGetconnection, the return value I get for say my f drive (driveLetter = f:) is 487, which is none of the errors defined (GetLastError returns the same). Can anyone see what I might be doing wrong? Or perhaps suggest an alternative?

Thanks, Tom.

0
boardtc
Asked:
boardtc
  • 3
  • 2
1 Solution
 
vladikaCommented:
ErrorCode 487 is ERROR_INVALID_ADDRESS.
You must allocate enough space for fullNetPath
Try
X := 0;
WNetGetconnection(PChar(driveLetter), '', x);
SetString(fullNetPath, nil, X);
 returnValue := WNetGetconnection(PChar(driveLetter), PChar(fullNetPath), x);
0
 
boardtcAuthor Commented:
Vladika,

Thanks a lot, that worked great. Is the only way to alocate space for fullNetPath to run WNetGetConnection twice?

I also want this function to work for 16-bit, currently I have:

            {$IFDEF WIN32}
            // allocate space for fullNetPath
            WNetGetconnection(PChar(driveLetter), '', x);
            SetString(fullNetPath, nil, x);
            returnValue := WNetGetconnection(PChar(driveLetter), PChar(fullNetPath),x);
            {$ELSE}
            returnValue := WNetGetconnection(@DriveLetter[1], @FullNetPath[1], @x);
            {$ENDIF}

returnValue is returning 51 here. I can't find what that means, do you have a list of return values somewhere (you knew 487)? Any ideas why the 16-bit version is not working?

Thanks a lot, Tom.

0
 
boardtcAuthor Commented:
Sorry, should have mentioned that I do:

   {$IFDEF WIN32}
   x: integer;
   {$ELSE}
   x: word;
  {$ENDIF}

   {$IFDEF WIN32}
   x := 0;
   {$ELSE}
   { make the size one less than the buffer }
   x := 255;
   {$ENDIF}

0
 
vladikaCommented:
Code 51 (in hex $33) is WN_BAD_LOCALNAME (see WinTypes.INT)
@DriveLetter[1] is NOT NULL-terminated string !!!

So, In Delphi 1

var
  PDriveLetter, PFullNetPath: PChar;
  X: Word;

// ......... code .......
  PDriveLetter := StrAlloc(Length(DriveLetter)+1);
  try
    PDriveLetter := StrPCopy(PDriveLetter, DriveLetter);
    X := 0;
    returnValue := WNetGetConnection(PDriveLetter, nil, @X);
    if X>256 then
      raise Exception.Create('FullNetPath too long !!!');
    if X <> 0 then
    begin
      PFullNetPath := StrAlloc(X);
      try
        returnValue := WNetGetConnection(PDriveLetter, PFullNetPath, @X);
        FullNetPath := StrPas(PFullNetPath);
      finally
        StrDispose(PFullNetPath);
      end;
    end;
  finally
    StrDispose(PDriveLetter);
  end;

// .....

The main strings difference in 16-bit and 32-bit Delphi is
In 16-bit Delphi string is SHORT string
In 32-bit Delphi string is LONG string

The short string type represents a statically-allocated string with maximum length between 1 and 255 characters, and a dynamic length between 0 and the maximum length. The short string type primarily exists for reasons of backward compatibility with earlier versions of Delphi and Borland Pascal.

The long string type represents a dynamically-allocated string with a maximum length limited only by available memory.

See Help in 32-bit Delphi.

Vladika.
0
 
boardtcAuthor Commented:
Vladika,

Many thanks again, I'm sure that will work. I should have seen the problame was because of the different strings. Thanks, Tom.
0
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.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now