Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How Do I Get the Drive Component of a UNC

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

Is there any functions that can return only the drive component from a unc string. It needs to include the machine name as well, such as \\machine\share$

Using VFP9...

Thanks, Stanley
 
Got it...
sys(5)

Well, NO I don't have it. As sys(5) reports the default directory.

I need a way to parse out the \\machine\drive part from an UNC string whether active or not.


Thanks,
Stanley
 
I thought there is no syntax like share$, a share simply is a normal share name, there is the syntax of \\server\c$, \\server\d$ etc for the local drives c,d etc on that server.

Googling reveals:
So you can actually do such share names, but they are shares like any other besides being hidden from normal listing in Windows Explorer, so they can be drives but in general are any shared folder. I don't see a way to turn UNC path to the local path at a server, but I also don't see a use for that. That translation has to be known server side, not client side. The shared drive or folder has its share name to be addressed and that's all you need to know client side.

What do you want to do? Do you want to determine available disc space in a whole domain? There are tools for that matter, hardware inventory tools or asset management. Take a look at WMI to make remote queries of win32_diskdrive, win32_share, etc., eg see
Don't reinvent that wheel.

Bye, Olaf.
 
There is ANETRESOURCES() listing network shares and network printers, but it's slow, I just mention it for sake of completeness, what you try to do is one realm of WMI and there are more specific solutions including hardware, eg IPMI, it's a wholle world of protocols and definitions about remote hardware management and controlling.

So if you want to collect info in that realm of hardware asset managment, look out for a ready to use software, there are experts for this and that's beyond desktop database business applications.

Bye, Olaf.
 
Besides all this, you find many threads here dealing with the opposite question: find out what UNC path a mapped drive letter is pointing to:

thread184-31156
thread184-469340
thread184-83388
thread184-1586145

But there are (typically) more shares than mapped drives, eg you don't have a drive letter mapped client side for any share. As far as I understand you'd like to know where the share really is located on the server side, ie which local drive letter and full path a share name means, and that is known to the computer owning the share, not client side, so you need remote procedure call or remote WMI connection or alike things to turn this remote question into the question about locally defined shares AT the server in question.

Bye, Olaf.
 
If your UNC string refers to a resource that may be available or not, then it is just a matter of checking on the naming convention.

Many ways of doing it, some more VFP down-to-earth than others. This uses regular expressions:

Code:
LOCAL lcUNCString AS String

m.lcUNCString = "\\A machine\A Share$\A folder"
MESSAGEBOX([UNC Share for "] + m.lcUNCString + [" is "] + JustUNCShare(m.lcUNCString) + ["])

m.lcUNCString = "\\A machine\A Share$"
MESSAGEBOX([UNC Share for "] + m.lcUNCString + [" is "] + JustUNCShare(m.lcUNCString) + ["])

m.lcUNCString = "\\A machine"
MESSAGEBOX([UNC Share for "] + m.lcUNCString + [" is "] + JustUNCShare(m.lcUNCString) + ["])

FUNCTION JustUNCShare (tcUNCResource AS String)

	ASSERT TYPE("m.tcUNCResource") = "C" MESSAGE "JustUNCShare() requires a string for parameter"

	IF !"_REGEXP.VCX" $ SET("Classlib")
		SET CLASSLIB TO (ADDBS(HOME(1)) + "ffc\_regexp.vcx") ADDITIVE
	ENDIF

	LOCAL loRegExpr AS _regexp

	m.loRegExpr = CREATEOBJECT("_regexp")
	m.loRegExpr.Pattern = "^\\\\[^\\]*\\[^\\]*"
	
	RETURN IIF(m.loRegExpr.Execute(m.tcUNCResource,.F.) = 1, m.loRegExpr.Matches[1,2], "")

ENDFUNC
 
Thanks guys,

In this particular case I'm testing if the drive that hosts a particular table has enough free disk space. The shared data path is stored in a local table and can include a drive letter path or an unc path. I test to see if it starts with '\\' and if so, I need to get and test the drive the unc is pointing to. It may be invalid or valid.

My question is really about parsing out the drive component so I can check for existence and if so, then check for its free space.

Based on atlopes script, it looks like

Code:
lcUNCString = '\\das\share$\myDir'
If Left(Alltrim(lcUNCString),2) = '\\'
	lcUnc=Left(lcUNCString, At('\',lcUNCString,4)-1)
	?lcUnc
Endif

can do the same thing with much less resources as the part I need to pass through the free space checker is the entire string up to the 4th '\'. Is there ever a case where my simple script would fail and atlopes script would get it right?

Thanks,
Stanley
 
If you're sure that the UNC path always includes a path component after the share, then your test is just fine.
 
Even knowing the drive letter of a network share, you won't be able to tell the servers drive X disc space, DISKSPACE() will take any drive letter for local drives or mapped drives and returns -1 for locally unknown letters. You have nothing from knowing the remote drive letter.

I don't know what else yiou have in mind, but wanting to know how much disc space is principially available at any UNC path, you don't need to shrink the path down at all. Eg look at DISKSPACE("C") vs. DISKSPACE("C:\Windows"). This suggests you simply take the path as is. You won't find out more knowing a remote drive letter. If you want to find out the local drive letter for a UNC path, then keep in mind, that there might be no mapping to a drive letter at all. There is no point in this. Determine DISKSPACE("\\server\share\folder\data\"), determine the disc space of the full path, there is no need to shorten this.

One more thing: You typically don't share a whole drive, you share a folder (and all its subfolder), so even the minimum \\server\share is NOT a drive, it's typically a folder. If you think every UNC path has a part of it matching a drive, than that's what's wrong. In the general case it's a folder and that of course belongs to some drive having a drive letter for the server. Your question simply put me in the wrong direction.

There is SHARE component in a UNC path, not a DRIVE component. If you really are interested in finding part of the UNC path up to the 4th "\", then you know the answer. You know AT().

And one final note: GetDiskFreeSpaceEx is having an lpDirectory[highlight #C17D11][/highlight]Name parameter, it also takes in a folder name.

Bye, Olaf.







 
Hi atlopes,

>> If you're sure that the UNC path always includes a path component after the share, then your test is just fine.

How other way could the drive component be referenced other that \\machine\drive_or_share name? Your script is also returning all characters up to the 4th backslash and must include 3 backslashes... correct?

Will your script handle all these variations of what a unc might look like?

\\machine\share\\machine\share
\\machine\share\sub\\machine\share\sub
\\machine\\machine

Thanks,
Stanley
 
This needed a small correction in the regular expression, to make sure something follows the slash after the server name. You can try for yourself:

Code:
LOCAL lcUNCTests AS String

TEXT TO m.lcUNCTests NOSHOW FLAGS 1
\\machine\share\\machine\share
\\machine\share\sub\\machine\share\sub
\\machine\\machine
ENDTEXT

LOCAL ARRAY laUNCTests(1)
ALINES(m.laUNCTests,m.lcUNCTests)

LOCAL lcUNCTest AS String

CLEAR
FOR EACH m.lcUNCTest IN m.laUNCTests
	? '"' + m.lcUNCTest + '" -> "' + JustUNCShare(m.lcUNCTest) + '"'
ENDFOR

FUNCTION JustUNCShare (tcUNCResource AS String)

	ASSERT TYPE("m.tcUNCResource") = "C" MESSAGE "JustUNCShare() requires a string for parameter"

	IF !"_REGEXP.VCX" $ SET("Classlib")
		SET CLASSLIB TO (ADDBS(HOME(1)) + "ffc\_regexp.vcx") ADDITIVE
	ENDIF

	LOCAL loRegExpr AS _regexp

	m.loRegExpr = CREATEOBJECT("_regexp")
	m.loRegExpr.Pattern = "^\\\\[^\\]*\\[^\\]+"
	
	RETURN IIF(m.loRegExpr.Execute(m.tcUNCResource,.F.) = 1, m.loRegExpr.Matches[1,2], "")

ENDFUNC

As Olaf said, you can throw a full UNC path including resources at DISKSPACE() and it will return ~available space, but this function makes sure (now...) that you have what is necessary: a server name and a share name.
 
Indeed, you're trying to solve a problem, which isn't existing at all.

Unless you tell me DISKSPACE("\\machine\share\sub\") results in -1, while DISKSPACE("\\machine\share\") or DISKSPACE("\\machine\share") gives a result.

If DISKSPACE does not work for one of the three UNC path versions, it also will not work for the others. GetDiskFreeSpaceEx then might have better "luck". Things like DISKSPACE or DRIVETYPE are far behind todays hardware landscape and it's surely better to use recent/stable Windows API functions for such system and device specific informations than old VFP language.

Bye, Olaf.
 
[tt]lcUNC = CreateObject("scripting.filesystemobject").GetDriveName(lcUNCString)[/tt]
 
Nice one. By its name it surely rather is intended for the usual path with drive letter, but it works for a share. It's misleading to name this part of a UNC path a drive anyway.

It also offers the proeprty Availablespace, but only for Drives, real drives:

FSO = CreateObject("scripting.filesystemobject")
? FSO.GetDrive("C").AvailableSpace

FSO.GetDrive("\\machine\share") will result in an error, because it is no drive, it's a share.

But again: You don't need this shrinked down UNC path at all. I just now tested under extreme conditions to get the diskspace of a remote drive I am only connected to via VPN, mapped as drive T.

I get the same value from

1. FSO.GetDrive("T").AvailableSpace
2. DISKSPACE("T")
3. DISKSPACE("\\server\share")
4. DISKSPACE("\\server\share\folder")

So it doesn't matter what you have, unless it's a valid path.

Bye, Olaf.
 
>> FSO.GetDrive("\\machine\share") will result in an error, because it is no drive, it's a share.

Yes, I also discovered that...


>> But again: You don't need this shrinked down UNC path at all.
Why not, as our main focus is to get away from mapped drives and use uncs.


Stanley
 
>Why not,
I'm not saying you need mapped drive letters, I'm saying you get the info from UNC paths, no matter if you shorten them or not.
There surely is a point in UNC for not needing a drive letter mapping, but there is no point in determininig the part of a unc path, that you might call the UNC drive. There is no such thing anyway.

You're chasing ghosts. What is so hard to understand about this?

You get the same available space of a drive, if you determine the available space of a folder on that drive. Why? Because any folder or sub-folder or sub-sub-folder in principle could use the rest of the available disk space. The situation would only differ for drive, share, and/or folder, if you'd ask for USED space, that of course differs.

Bye, Olaf.
 
>Becausre any folder or subfolder or subsubfolder in principle could use the rest of the available disk

Not if folder quotas are applied with hard limits
 
Fine, strongm.

Because that again speaks for determining the available space of a certain folder anyway. It again speaks against first finding out the part of a UNC path, that is just the share name.
In the end, if you have paths in some table, no matter if UNC or normal, you can determine their available space, there is no need to shorten them first.

Bye, Olaf.
 
Hi Olaf,

OK, I see that
diskspace("\\machine\share")
and
diskspace("\\machine\share\validdir\validsubdir")

returns the same values, in my no quota system I would not need to shorten the url. However, considering what strongm mentions about quotas, then I should shorten the unc????

>> that you might call the UNC drive. There is no such thing anyway.
I disagree, as "\\machine\share" represents a share without folders and would be the minimum pointer to that resource. We know that a share implies a folder, therefore is strongm's quota argument valid if the folder with a quota is at the share's root? Would "\\machine\share" return the same free space value as "\\machine\share\quotafolder"?

Thank you for pointing this out.
Stanley

 
What did I say about strongms argument of quotas?
myself said:
that again speaks for determining the available space of a certain folder anyway

If you care to know the available space (taking quoata into account) of a folder, then ask for diskspace of that folder. First finding out the "drive" doesn't help here, in the best case it'll return the same space, as there are no quotas, in the worst case, it'll tell you about more available space, which you can't use and you get a false positive for enough space for your backup. You don't want that false positive and then fail to save the backup, do you?

You want to know the DISKSPACE of the place you want to save to, especially taking quotas into account. The space available overall on a whole share or drive then doesn't matter. It will only be of interest, when the user chooses another folder in the same share without a quota, or the share root. But then again, your only interest is the disk space of the alternative path the user selects, nothing else.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top