cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
peterbi
Level 7

Forwarded: get all mapped drives on Vista

This is my post to microsoft.public.win32.programmer.networks group, but not sure if it's more proper to post here.

I am struggling to get all mapped drives on Vista (with UAC on, without EnableLinikedConnections reg entry) during installation of an InstallScript (no MSI) product with 'Administration' execution level, which is created with IS2009.

Due to the famous Vista discrepancy of 'non-elevated' and 'elevated' admin users login context, mapped drives created before 'elevation' are invisible to the installer, which is elevated. I want to have a function/tool that escape the discrepancy on Vista. Some people talked about WNet... APIs, but the function below seems not working - it gives all mapped drives on XP (so don't suspect about other possible code errors, etc.), but none on Vista. Here is the way I call it inside InstallShield script:

if ( UseDLL( SRCDIR ^ "MYDLL.dll" ) < 0 ) then
MessageBox("Cant' load MYDLL.dll", INFORMATION);
abort;
else
MessageBox("Loaded MYDLL.dll", INFORMATION);
nRet = GetAllMappedDrives(sDrives);
MessageBox("sDrives is "+sDrives, INFORMATION);
NumToStr(sRet, nRet);
MessageBox("sRet is " + sRet, INFORMATION);
endif;


This is in reply to Jialiang Ge at http://groups.google.com/group/microsoft.public.win32.programmer.networks/browse_thread/thread/e6071602cf1911e2


What (or which API) is the right way to get mapped drives on Vista? I used the following function to get mapped drives on Vista (please note that I made the function as an exported dll function, and called the function inside InstallShield script code), but it failed, the exact the same code worked on XP. So my guess is that either the WNet... APIs are not working on Vista, or InstallShield script has problem to execute the APIs properly on Vista.

UINT WINAPI GetAllMappedDrives
(
char* szMapDrives // ......
)
{
static const int ILETTERLEN = 8;
static const int IDRIVEINFLEN = MAX_PATH*2;

DWORD ui = 0,ulBuf = 16384,ulEntries = 0xFFFFFFFF,ulErr = 0;
int iErr = 0;
HANDLE hEnum = 0;
LPNETRESOURCE pDrive = 0;
char cDriveInfo[IDRIVEINFLEN];
TCHAR tcRemoteName[MAX_PATH],tcProvider[MAX_PATH],tcLetter[ILETTERLEN];
char* szDriveInfo = (char*)cDriveInfo;
char* szRemoteName = (char*)tcRemoteName;
char* szProvider = (char*)tcProvider;
char* szLetter = (char*)tcLetter;

ulErr = WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,0,0,&hEnum);
if (ulErr != NO_ERROR) return -5;

do {
pDrive = (LPNETRESOURCE)GlobalAlloc(GPTR,ulBuf);
ulErr = WNetEnumResource(hEnum,&ulEntries,pDrive,&ulBuf);
if (ulErr == NO_ERROR) {
iErr = ulEntries;
for (ui=0; ui // Pull data out of resource structure.
sprintf_s(szLetter,ILETTERLEN,"%s",pDrive[ui].lpLocalName);
if (!strcmp(szLetter,"(null)")) {
strcat_s(szLetter,ILETTERLEN,":");
}
sprintf_s(szRemoteName,MAX_PATH,"%s",pDrive[ui].lpRemoteName);
sprintf_s(szProvider,MAX_PATH,"%s",pDrive[ui].lpProvider);

// Copy the drive information.
strcpy_s(szDriveInfo,IDRIVEINFLEN,"?");
strcat_s(szDriveInfo,IDRIVEINFLEN,szLetter);
strcat_s(szDriveInfo,IDRIVEINFLEN,szRemoteName);
strcat_s(szDriveInfo,IDRIVEINFLEN,":");
strcat_s(szDriveInfo,IDRIVEINFLEN,szProvider);
strcat(szMapDrives,szDriveInfo);
}
} else if (ulErr != ERROR_NO_MORE_ITEMS) {
GlobalFree((HGLOBAL)pDrive);
iErr = -2;
break;
} else if (ulErr == ERROR_MORE_DATA) {
GlobalFree((HGLOBAL)pDrive);
iErr = -3;
break;
} else if (ulErr == ERROR_INVALID_HANDLE ||
ulErr == ERROR_NO_NETWORK ||
ulErr == ERROR_EXTENDED_ERROR) {
GlobalFree((HGLOBAL)pDrive);
iErr = -4;
break;
}
GlobalFree((HGLOBAL)pDrive);
} while (ulErr != ERROR_NO_MORE_ITEMS);

WNetCloseEnum(hEnum);
return iErr;
}


Please advice.


Thanks,
Peter
Labels (1)
0 Kudos
(3) Replies
peterbi
Level 7

Is it possible to programmatically do 'Net User' and 'Run as Administrator' execution? I mean to do it inside InstallScript code during installation?

I tried the following in my ISScript function with LaunchApplication(), it should be executed successfully at install, but the drive is still not mapped properly (having problem to launch shortcut), but once I manually run 'net use ...' with "Run as Administrator", all works immediatly. I am stuck.:(



LAAW_SHELLEXECUTEVERB = "runas";
nReturn = LaunchApplication(WINSYSDIR^"CMD.exe", "NET USE "+szMappedDrive+" "+szDisk,
"", SW_HIDE, LAAW_OPTION_WAIT, LAAW_OPTION_USE_SHELLEXECUTE);
if (nReturn != ISERR_SUCCESS) then
MessageBox("LaunchApplication() failed to map the drive", INFORMATION);
endif;



Any suggestions?

Thanks,
Peter
0 Kudos
Paul_Boerefijn
Level 3

Try adding /c in your parameters. maybe that will help you.
C:\windows\system32\cmd.exe /c Net use 😧 \\server\share
0 Kudos
joshstechnij
Level 10 Flexeran
Level 10 Flexeran

Please note that mapped drives are associated with a logon session (not to be confused with terminal server sessions). A process running non-elevated and another process running elevated are a part of two distinct logon sessions. As such, if a drive was mapped in a non-elevated context, it will never be visible to an elevated context, unless the drive is also mapped in the elevated context.

For a nitty-gritty low level detail on why this occurs, please reference the following article:
The kernel object namespace and Win32, part 3
0 Kudos