Jump to content

DriveMapGet fails when AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator is set.


TroyT
 Share

Recommended Posts

DriveMapGet fails when AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator is set. 

The drive is mapped and DriveMapGet reports the drive as mapped when AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator is not set, and fails to detect that the drive is mapped when AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator is set.  I'm sure I'm just missing something.

Here is the code:

#include <File.au3>
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>

Local $sDrive = "B:"
Local $sAppPath = DriveMapGet($sDrive)& "\Apps\App.exe"
Local $sWorkingFolder = DriveMapGet($sDrive)& "\Apps"
Local $sCmdLine = "/controlfile  Rfile.pot"

if ("" = DriveMapGet($sDrive)) Then
    MsgBox( $MB_OK, "Error - No Drive mapping", "The " &$sDrive & " is not mapped.")
Else
    ;Check to see if we can find the exe file.
    if FileExists( $sAppPath ) Then

        if FileExists( $sWorkingFolder & "\Rfile.pot" ) Then
            Local $iPID = ShellExecute ( $sAppPath , $sCmdLine, $sWorkingFolder )
        Else
            MsgBox( $MB_OK, "ERROR - File not found!", "Can not locate file: " & $sWorkingFolder & "\Rfile.pot" )
        EndIf

    Else
        MsgBox( $MB_OK, "ERROR - File not found!", "Can not locate file: " & $sAppPath )
    EndIf
EndIf

 

Thanks in advance.

Troy

Link to comment
Share on other sites

  • Developers

Are you using the exact same credentials when running elevated ?

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Here's a proof of concept:

#include <Array.au3>
#include <MsgBoxConstants.au3>
#include <ProcessConstants.au3>
#include <Security.au3>
#include <SecurityConstants.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WinAPIFiles.au3>

Global $b_AddNetworkDrives = True
Global $g_CmdLineRaw = $CmdLineRaw

If Not @Compiled Then
    MsgBox(0, "Hint", "Run program compiled to test...")
    Exit
EndIf

If StringInStr($g_CmdLineRaw, "SMF_GetMappedDrives", 2) Then
    ; Executed by non-elevated Child process
    If Not IsAdmin() Then _UAC_GetMappedDrives_Child()
    Exit

ElseIf Not IsAdmin() Then
    ; Run elevated Main process

    ; !!! HINT !!!
    ; > The UAC elevated process MUST NOT contain a manifest with the "requestedExecutionLevel = requireAdministrator"
    ; > the _RunNonElevated() function will not work for these executables
    ; > instead manually start the process with elevated rights manually, either through the "runas" verb or by right-click
    ; !!! HINT !!!
    ShellExecute(@ScriptFullPath, "", @WorkingDir, "runas")
    Exit

EndIf

If $b_AddNetworkDrives Then
    ; Executed by elevated Main process
    If IsAdmin() Then _UAC_GetMappedDrives_Parent()
EndIf

Exit

Func _UAC_GetMappedDrives_Parent()

    Local $tSecurity = DllStructCreate("int Length;ptr Descriptor;int InheritHandle") ; $tagSECURITY_ATTRIBUTES
    DllStructSetData($tSecurity, 1, DllStructGetSize($tSecurity))
    DllStructSetData($tSecurity, 2, 0)

    Local $hFileMap = _WinAPI_CreateFileMapping(-1, 65536, "SMF_MappedDrives_Buffer", 0x0004, DllStructGetPtr($tSecurity))

    Local $iPID = _RunNonElevated('"' & @ScriptFullPath & '" SMF_GetMappedDrives')
    ProcessWaitClose($iPID, 10)

    Local $pAddress = _WinAPI_MapViewOfFile($hFileMap)
    Local $tData = DllStructCreate('wchar[32768]', $pAddress)
    Local $s_MappedDrives_Data_Child = DllStructGetData($tData, 1)
    _WinAPI_UnmapViewOfFile($pAddress)
    _WinAPI_CloseHandle($hFileMap)

    Local $aDrives_Child
    If Not StringInStr($s_MappedDrives_Data_Child, "GetMappedDrives Results - Child:") Then
        Local $aDrives_Child[1]
        $aDrives_Child[0] = -1 ; Error, no info transfered from non-elevated process
    Else
        $s_MappedDrives_Data_Child = StringReplace($s_MappedDrives_Data_Child, "GetMappedDrives Results - Child:" & @LF, "")
        $aDrives_Child = StringSplit($s_MappedDrives_Data_Child, @LF)
        StringReplace($s_MappedDrives_Data_Child, @LF, "") ; Detect number of lines in data = number of found mappings
        $aDrives_Child[0] = @extended
    EndIf

    Local $aDrives = DriveGetDrive("NETWORK")
    If @error Or Not IsArray($aDrives) Then
        Local $aDrives[1]
        $aDrives[0] = 0
    EndIf

    Local $a_Drive_Mapping[28][5]
    $a_Drive_Mapping[0][1] = "Elevated Mode"
    $a_Drive_Mapping[0][3] = "Non-Elevated Mode"
    $a_Drive_Mapping[0][4] = "Number of Differences in mapped drives"
    $a_Drive_Mapping[1][1] = $aDrives[0] ; Number of Mapping in Elevated mode
    $a_Drive_Mapping[1][3] = $aDrives_Child[0] ; Number of Mapping in Non-Elevated mode
    $a_Drive_Mapping[1][4] = 0 ; Number of differences in mapped drive paths

    Local $aDrives_Child_Split

    For $i = 2 To 27

        $a_Drive_Mapping[$i][0] = Chr($i + 95) & ":"

        For $y = 1 To $aDrives[0]
            If $aDrives[$y] = Chr($i + 95) & ":" Then
                $a_Drive_Mapping[$i][1] = DriveMapGet($aDrives[$y])
                $a_Drive_Mapping[$i][2] = DriveStatus($a_Drive_Mapping[$i][1])
                ExitLoop
            EndIf
        Next

        For $y = 1 To $aDrives_Child[0]
            If StringLeft($aDrives_Child[$y], 3) = Chr($i + 95) & ":=" Then

                $aDrives_Child[$y] = StringTrimLeft($aDrives_Child[$y], 3)

                $aDrives_Child_Split = StringSplit($aDrives_Child[$y], "|")
                If $aDrives_Child_Split[0] = 2 Then
                    $a_Drive_Mapping[$i][3] = $aDrives_Child_Split[1]
                    $a_Drive_Mapping[$i][4] = $aDrives_Child_Split[2]
                EndIf

                ExitLoop
            EndIf
        Next

        If $a_Drive_Mapping[$i][1] <> $a_Drive_Mapping[$i][3] Then $a_Drive_Mapping[1][4] += 1

    Next

    If $a_Drive_Mapping[1][4] > 0 Then
        ; add action if difference in mappings found
    EndIf

    _ArrayDisplay($a_Drive_Mapping, IsAdmin())

EndFunc   ;==>_UAC_GetMappedDrives_Parent

Func _UAC_GetMappedDrives_Child()

    Local $s_MappedDrives_Data = "GetMappedDrives Results - Child:" & @LF

    Local $aDrives = DriveGetDrive("NETWORK")
    If Not @error Then
        For $i = 1 To $aDrives[0]
            $s_MappedDrives_Data &= $aDrives[$i] & "=" & DriveMapGet($aDrives[$i]) & "|" & DriveStatus($aDrives[$i]) & @LF
        Next
    EndIf


    Local $hFileMap = _WinAPI_OpenFileMapping("SMF_MappedDrives_Buffer")

    Local $pAddress = _WinAPI_MapViewOfFile($hFileMap)
    Local $tData = DllStructCreate('wchar[32768]', $pAddress)
    DllStructSetData($tData, 1, $s_MappedDrives_Data)
    _WinAPI_UnmapViewOfFile($pAddress)

    _WinAPI_CloseHandle($hFileMap)

EndFunc   ;==>_UAC_GetMappedDrives_Child




Func _RunNonElevated($sCommandLine = "")
    If Not IsAdmin() Then Return Run($sCommandLine) ; if current process is run non-elevated then just Run new one.

    ; Structures needed for creating process
    Local $tSTARTUPINFO = DllStructCreate($tagSTARTUPINFO)
    Local $tPROCESS_INFORMATION = DllStructCreate($tagPROCESS_INFORMATION)

    ; Process handle of some process that's run non-elevated. For example "Explorer"
    Local $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, 0, ProcessExists("explorer.exe"))

    ; If successful
    If $hProcess Then
        ; Token...
        Local $hTokOriginal = _Security__OpenProcessToken($hProcess, $TOKEN_ALL_ACCESS)
        ; Process handle is no longer needed. Close it
        _WinAPI_CloseHandle($hProcess)
        ; If successful
        If $hTokOriginal Then
            ; Duplicate the original token

            ; https://stackoverflow.com/questions/7004310/bypassing-elevation-when-launching-a-new-process
            ; SetEnvironmentVariable function
            ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms686206(v=vs.85).aspx

            Local $hTokDuplicate = _Security__DuplicateTokenEx($hTokOriginal, $TOKEN_ALL_ACCESS, $SECURITYIMPERSONATION, $TOKENPRIMARY)
            ; Close the original token
            _WinAPI_CloseHandle($hTokOriginal)
            ; If successful
            If $hTokDuplicate Then
                ; Create process with this new token

                Local $aRet = DllCall("kernel32.dll", "int", "SetEnvironmentVariable", "str", "__compat_layer", "str", "RunAsInvoker")

                _Security__CreateProcessWithToken($hTokDuplicate, 0, $sCommandLine, 0, @ScriptDir, $tSTARTUPINFO, $tPROCESS_INFORMATION)

                ; Close that token
                _WinAPI_CloseHandle($hTokDuplicate)
                ; Close get handles
                _WinAPI_CloseHandle(DllStructGetData($tPROCESS_INFORMATION, "hProcess"))
                _WinAPI_CloseHandle(DllStructGetData($tPROCESS_INFORMATION, "hThread"))
                ; Return PID of newly created process
                Return DllStructGetData($tPROCESS_INFORMATION, "ProcessID")
            EndIf
        EndIf
    EndIf
EndFunc   ;==>_RunNonElevated

 

Link to comment
Share on other sites

  • 1 month later...

putting this Q here for now ..

When not having a network drive to test this all out as in my case ..
In your best opinion how will the "net use" command should look like -> "tested"  (if it can help in using a mapped drive from an admin privileged script ..?)

* If I map a vmware drive it will show as a fixed drive type and non accessible from an admin privileged script
Also DriveMapGet will fail either ways since it doesn't get the UNC Path in this case ..

And I also want to distinguish when a drive can be accessed like  Z:\folder   never like: \\server\path\folder  And work with the drive in admin mode if the "net use" command proves to work

when using DriveGetDrive("NETWORK")  will i also need to  DriveMapGet("Z:")  it to check if its mapped or will it give UNC paths (if not mapped)  ?

Thanks

Link to comment
Share on other sites

at least i'll need to know what do you get for DriveGetDrive("NETWORK") is it essentially a mapped drive or a discovered network drive returning a UNC path "\\" , Can it be accessed like Z:\folder\some_file.ext

anyone ..
Thanks

Link to comment
Share on other sites

well, it just uses a test app that searches for stuff. no major changes. working folder, drive that is mapped, etc. not like you could reproduce it. mine works properly with admin rights granted or not, but, I have UAC turned all the way down I believe, checked, no I don't. I don't know what kind of issue he is having. it works either way, same for me. His code with my drive and folder info.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <File.au3>
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>

Local $sDrive = "S:"
Local $sAppPath = DriveMapGet($sDrive)& "\public\company\listfiles.exe"
Local $sWorkingFolder = DriveMapGet($sDrive)& "\public\company"
Local $sCmdLine = "d: *.pdf"

if ("" = DriveMapGet($sDrive)) Then
    MsgBox( $MB_OK, "Error - No Drive mapping", "The " &$sDrive & " is not mapped.")
Else
    ;Check to see if we can find the exe file.
    if FileExists( $sAppPath ) Then

;~         if FileExists( $sWorkingFolder & "\Rfile.pot" ) Then
            Local $iPID = ShellExecute ( $sAppPath , $sCmdLine, $sWorkingFolder )
;~         Else
;~             MsgBox( $MB_OK, "ERROR - File not found!", "Can not locate file: " & $sWorkingFolder & "\Rfile.pot" )
;~         EndIf

    Else
        MsgBox( $MB_OK, "ERROR - File not found!", "Can not locate file: " & $sAppPath )
    EndIf
EndIf

 

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

2 minutes ago, Deye said:

SO if I had to use FileCopy ( "Z:\folder\some_file.ext", $dest ) when its a mapped drive will this then fail ?

Earthshine,

 did you try running it with #RequireAdmin ?

 

YES. Admin or not, it worked fine. I can call any app on that directory.

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...