GeorgeR

DriveGetDrive Issue

17 posts in this topic

#1 ·  Posted (edited)

Hello forum,

What I am trying to do: I call an autoit executable from php in order to get system drives and their basic info. The script is quite simple, and the result is in JSON format:

;include libraries
   #include <Array.au3>

   ;This is the output array
   Dim $JSON[0]

   ;Get all drives
   $AllDrivesArray = DriveGetDrive("ALL")

   For $i = 1 To $AllDrivesArray[0]

      _ArrayAdd($JSON,'"drive": {"DrivePath": "'&$AllDrivesArray[$i]&'","DriveType": "'&DriveGetType($AllDrivesArray[$i]&"\")&'","DriveLabel": "'&DriveGetLabel($AllDrivesArray[$i]&"\")&'"}')

   Next

   ;This is the output json object
   $JSON = "{"&_ArrayToString($JSON,',')&"}"

   consolewrite($JSON)

This is a simple response of the above script, when i run it through Scite:

{"drive": {"DrivePath": "c:","DriveType": "Fixed","DriveLabel": ""},"drive": {"DrivePath": "d:","DriveType": "CDROM","DriveLabel": ""},"drive": {"DrivePath": "z:","DriveType": "Network","DriveLabel": ""}}

Now comes the issue. When I compile it, and call it from php, I am unable to get the network drive. I only get C: and D: drives. The same thing happens when I right click the .exe from windows and I run it with my account (Administrator member): I can only see C: and D: drives! Any ideas why I face this behavior and how it can be bypassed?

Edited by GeorgeR

Share this post


Link to post
Share on other sites



Welcome to AutoIt and the forum!

When you run the compiled script with the same user as SciTe, do you get the expected result?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Hi water and thank you for your quick response,

I login to the pc with my account: George, member of Administrators group.

  • when i run it through Scite editor(F5 button) i get what i want.
  • when i compile to .exe and i run the exe, i get what i want.
  • when i compile to .exe and i run the exe with run as and enter my credentials(George and my password) i don't get what i wan't
  • when i call the exe from php (apache runs with my account: George and my password), i don't get what i wan't.

Isn't it strange?

Edited by GeorgeR

Share this post


Link to post
Share on other sites

How I understand it:
I assume that all network drives are assigned by a logon script. When you provide the credentials of another use this script isn't executed. Hence the network drives are missing.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

The user is the same for all cases. George and the password... I am the only administrator in my pc. And all the network drives are located in my pc.

Share this post


Link to post
Share on other sites

How do you assign the Network Drive to your account?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

A script controls its own mapping of drives. i.e, Script Tom runs script and sees drives as Tom as seeing mapped network drives of Tom. Script Tom runs as other user does not see mapped network drives. Admin allocated network drives not seen ... and on it goes. Based on permissions. Admin does not see user mapped drives.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Let me make more simple (Forget the php-apache stuff):

I have an account in windows : George, member of administrators group. I login to the pc with this account.

When i double click the .au3 file containing the snippet of my first post and I press F5, I see three drives. C:, D: and Z:

When i right click the .au3 file and select run as a different user, and i enter the exact same credentials I used to login to windows (George account) with F5 I can only see two drives: C: and D:

I am trying to think what makes the difference but i can't! Any thoughts?

Edited by GeorgeR

Share this post


Link to post
Share on other sites

As I asked in post #6: How do you access drive Z:? When you run a script with a different user the environment for this user is created with the passed credentials BUT the login script or whatever assigns drive Z: isn't executed.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Seems strange. When you double start the au3 file, you are the user George.

When you runas George, you are most probably using the admin token of George and cannot see the user George network drives. Perhaps a side effect of UAC.

Just an observation. Unless you are admin initially and runas is just churning you into a simple (limited) user.

Share this post


Link to post
Share on other sites

Seems strange. When you double start the au3 file, you are the user George.

When you runas George, you are most probably using the admin token of George and cannot see the user George network drives. Perhaps a side effect of UAC.

Just an observation. Unless you are admin initially and runas is just churning you into a simple (limited) user.

I've just tried with UAC off, and still no result. The Z: drive denies to appear!

Share this post


Link to post
Share on other sites

Using Google returns a lot of hits. One of them describes the problem


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

GeorgeR,

My observation still stands. Upon running the script as you have stated and I can confirm, as user, the drives do show including the network drives.

Running runas gives me a UAC prompt. I go humm, click OK. I see drives but no network drives show. The admin me cannot access/see the user me drives.

You may find documentation (MSDN) about scripts needing to map their own network drives if runas/elevation is being used to change the user. In your case, you are George but not the same George (yeah, sounds insane). i.e. you are using a different token as in different permissions. I would expect it to work with UAC off though perhaps water has a point with it being an OS issue.

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Water, Mhz, KaFu

Thank you all for your time and reasearch. I've been searching the issue on google, and I've already found some of the mentioned resources without success (the EnableLinkedConnection KEY from regedit and the run as>net use etc). I will continue my research tomorrow and update you in case of a solution!

Anyway I really appreciate your help!

Edited by GeorgeR

Share this post


Link to post
Share on other sites

One thing I think I remember from my research is, that you can map the missing drive in the user context with DriveMapAdd(). I started a script to synchronize to drive mappings under different user contexts, but somehow lost the interest (will be an addition to SMF when my interest starts again ^_^). Here's the current state, I guess you'll have to insert some includes :shhh:...

 

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

; DriveMapDel("b:")
; DriveMapAdd("b:","\\diskstation\nas",8)

#include <array.au3>
Global $b_AddNetworkDrives = True
Global $g_CmdLineRaw = $CmdLineRaw

$h_DLL_Kernel32 = DllOpen("kernel32.dll")
$h_DLL_Advapi32 = DllOpen("advapi32.dll")

#include <WinAPIEx_3.8_3380\WinAPIEx.au3>

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



; Add to top of SMF_Func_ShellTristateTreeView_v64.au3 ?
If StringInStr($g_CmdLineRaw, "SMF_GetMappedDrives", 2) Then
    If Not IsAdmin() Then _UAC_GetMappedDrives_Child()
    Exit
EndIf



; Add to func _ShellTreeView_Create(
If $b_AddNetworkDrives Then
    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 $s_AutoItWinGetTitle = AutoItWinGetTitle()
    AutoItWinSetTitle("")
    _RunWithReducedPrivileges(@ScriptFullPath, " SMF_GetMappedDrives", @ScriptDir, @SW_HIDE, True)
    AutoItWinSetTitle($s_AutoItWinGetTitle)

    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 ; different 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




; send result to main process

; in main process do something like...
; - check if any mappings existed before > on exit remove only newly "added" mappings
; > remove "Old added" mappings before reload!
; DriveMapAdd($aDrives[$i],DriveMapGet($aDrives[$i]),8)




; ===============================================================================================================================
; <_RunWithReducedPrivileges.au3>
;
; Function to run a program with reduced privileges.
;   Useful when running in a higher privilege mode, but need to start a program with reduced privileges.
;   - A common problem this fixes is drag-and-drop not working, and misc functions (sendmessage, etc) not working.
;
; Functions:
;   _RunWithReducedPrivileges()     ; runs a process with reduced privileges if currently running in a higher privilege mode
;
; INTERNAL Functions:
;   _RWRPCleanup()      ; Helper function for the above
;
; Reference:
;   See 'Creating a process with Medium Integration Level from the process with High Integration Level in Vista'
;       @ http://www.codeproject.com/KB/vista-security/createprocessexplorerleve.aspx
;     See Elmue's comment 'Here the cleaned and bugfixed code'
;   Also see: 'High elevation can be bad for your application: How to start a non-elevated process at the end of the installation'
;       @ http://www.codeproject.com/KB/vista-security/RunNonElevated.aspx
;     (Elmue has the same code here too in his response to FaxedHead's comment ('Another alternative to this method'))
;   Another alternative using COM methods:
;     'Getting the shell to run an application for you - Part 2:How | BrandonLive'
;       @ http://brandonlive.com/2008/04/27/gettin...o-run-an-application-for-you-p
;
; Author: Ascend4nt, based on code by Elmue's fixed version of Alexey Gavrilov's code
; ===============================================================================================================================

; ===================================================================================================================
; Func _RunWithReducedPrivileges($sPath,$sCmd='',$sFolder='',$iShowFlag=@SW_SHOWNORMAL,$bWait=False)
;
; Function to run a program with reduced privileges.
;   Useful when running in a higher privilege mode, but need to start a program with reduced privileges.
;   - A common problem this fixes is drag-and-drop not working, and misc functions (sendmessage, etc) not working.
;
; $sPath = Path to executable
; $sCmd = Command-line (optional)
; $sFolder = Folder to start in (optional)
; $iShowFlag = how the program should appear on startup. Default is @SW_SHOWNORMAL.
;   All the regular @SW_SHOW* macros should work here
; $bWait = If True, waits for the process to finish before returning with an exit code
;   If False, it returns without waiting for the process to finish, with the process ID #
;
; Returns:
;   Success: If $bWait=True, the exit code of the Process. If $bWait=False, then the Process ID # of the process
;   Failure: 0, with @error set:
;       @error = 2 = DLLCall error. @extended contains the DLLCall error code (see AutoIt Help)
;       @error = 3 = API returned failure. Call 'GetLastError' API function to get more info.
;
; Author: Ascend4nt, based on code by Elmue's fixed version of Alexey Gavrilov's code
; ===================================================================================================================

Func _RunWithReducedPrivileges($sPath, $sCmd = '', $sFolder = '', $iShowFlag = @SW_SHOWNORMAL, $bWait = False)
    Local $aRet, $iErr, $iRet = 1, $hProcess, $hToken, $hDupToken, $stStartupInfo, $stProcInfo
    Local $sCmdType = "wstr", $sFolderType = "wstr"

;~  Run normally if not in an elevated state, or if pre-Vista O/S
    ; If Not IsAdmin() Or StringRegExp(@OSVersion, "_(XP|200(0|3))") Then ; XP, XPe, 2000, or 2003?
    If Not IsAdmin() Or $__WINVER < 0x0600 Then ; XP or less then
        ; MsgBox(0,"_RunWithReducedPrivileges",IsAdmin() & @crlf & "0x" & hex($__WINVER,4))
        If $bWait Then Return RunWait($sPath & ' ' & $sCmd, $sFolder)
        Return Run($sPath & ' ' & $sCmd, $sFolder)
    EndIf

;~  Check Parameters and adjust DLLCall types accordingly
    If Not IsString($sCmd) Or $sCmd = '' Then
        $sCmdType = "ptr"
        $sCmd = 0
    EndIf
    If Not IsString($sFolder) Or $sFolder = '' Then
        $sFolderType = "ptr"
        $sFolder = 0
    EndIf
    #cs
        ; STARTUPINFOW struct: cb,lpReserved,lpDesktop,lpTitle,dwX,dwY,dwXSize,dwYSize,dwXCountChars,dwYCountChars,dwFillAttribute,
        ;   dwFlags,wShowWindow,cbReserved2,lpReserved2,hStdInput,hStdOutput,hStdError
        ;   NOTE: This is for process creation info. Also, not sure if the Std I/O can be redirected..?
    #ce
    $stStartupInfo = DllStructCreate("dword;ptr[3];dword[7];dword;word;word;ptr;handle[3]")
    DllStructSetData($stStartupInfo, 1, DllStructGetSize($stStartupInfo))
    DllStructSetData($stStartupInfo, 4, 1) ; STARTF_USESHOWWINDOW
    DllStructSetData($stStartupInfo, 5, $iShowFlag)

    ; PROCESS_INFORMATION struct: hProcess, hThread, dwProcessId, dwThreadId
    ;   This is for *receiving* info
    $stProcInfo = DllStructCreate("handle;handle;dword;dword")

;~  Open a handle to the Process
    ; Explorer runs under a lower privilege, so it is the basis for our security info.
    ;   Open the process with PROCESS_QUERY_INFORMATION (0x0400) access
    $aRet = DllCall($h_DLL_Kernel32, "handle", "OpenProcess", "dword", 0x0400, "bool", False, "dword", ProcessExists("explorer.exe"))
    If @error Then Return SetError(2, @error, 0)
    If Not $aRet[0] Then Return SetError(3, 0, 0)
    $hProcess = $aRet[0]

;~  Open a handle to the Process's token (for duplication)
    ; TOKEN_DUPLICATE = 0x0002
    $aRet = DllCall($h_DLL_Advapi32, "bool", "OpenProcessToken", "handle", $hProcess, "dword", 2, "handle*", 0)
    If @error Then Return SetError(_RWRPCleanup($hProcess, 0, 0, 2, @error), @extended, 0)
    If $aRet[0] = 0 Then Return SetError(_RWRPCleanup($hProcess, 0, 0, 3), @extended, 0)
    $hToken = $aRet[3]

;~  Duplicate the token handle
    ; TOKEN_ALL_ACCESS = 0xF01FF, SecurityImpersonation = 2, TokenPrimary = 1,
    $aRet = DllCall($h_DLL_Advapi32, "bool", "DuplicateTokenEx", "handle", $hToken, "dword", 0xF01FF, "ptr", 0, "int", 2, "int", 1, "handle*", 0)
    If @error Then Return SetError(_RWRPCleanup($hProcess, $hToken, 0, 2, @error), @extended, 0)
    If Not $aRet[0] Then Return SetError(_RWRPCleanup($hProcess, $hToken, 0, 3), @extended, 0)
    $hDupToken = $aRet[6]

;~  Create the process using 'CreateProcessWithTokenW' (Vista+ O/S function)
    $aRet = DllCall($h_DLL_Advapi32, "bool", "CreateProcessWithTokenW", "handle", $hDupToken, "dword", 0, "wstr", $sPath, $sCmdType, $sCmd, _
            "dword", 0, "ptr", 0, $sFolderType, $sFolder, "ptr", DllStructGetPtr($stStartupInfo), "ptr", DllStructGetPtr($stProcInfo))
    $iErr = @error
    _RWRPCleanup($hProcess, $hToken, $hDupToken, 2, @error)
    If $iErr Then Return SetError(2, $iErr, 0)
    If Not $aRet[0] Then Return SetError(3, 0, 0)

;~  MsgBox(0,"Info","Process info data: Process handle:"&DllStructGetData($stProcInfo,1)&", Thread handle:"&DllStructGetData($stProcInfo,2)& _
;~      ", Process ID:"&DllStructGetData($stProcInfo,3)&", Thread ID:"&DllStructGetData($stProcInfo,4)&@CRLF)

    $iRet = DllStructGetData($stProcInfo, 3) ; Process ID

;~  If called in 'RunWait' style, wait for the process to close
    If $bWait Then
        ProcessWaitClose($iRet)
        $iRet = @extended ; Exit code
    EndIf

;~  Close Thread and then Process handles (order here is important):
    _RWRPCleanup(0, DllStructGetData($stProcInfo, 2), DllStructGetData($stProcInfo, 1), 0)

    Return $iRet
EndFunc   ;==>_RunWithReducedPrivileges

; ===================================================================================================================
; Func _RWRPCleanup($hProcess,$hToken,$hDupToken,$iErr=0,$iExt=0)
;
; INTERNAL: Helper function for _RunWithReducedPrivileges()
;
; Author: Ascend4nt
; ===================================================================================================================

Func _RWRPCleanup($hProcess, $hToken, $hDupToken, $iErr = 0, $iExt = 0)
    Local $aHandles[3] = [$hToken, $hDupToken, $hProcess] ; order is important
    For $i = 0 To 2
        If $aHandles[$i] <> 0 Then DllCall($h_DLL_Kernel32, "bool", "CloseHandle", "handle", $aHandles[$i])
    Next
    Return SetExtended($iExt, $iErr)
EndFunc   ;==>_RWRPCleanup

 

1 person likes this

Share this post


Link to post
Share on other sites

Thank you all for your help.I was unable to do it after many hours of trying! But I won't quit. It looks like I will have to live without this functionality at least for now...

This is what I am trying to do - hopefully I will post a tutorial on the relevant forum section... I have a server side autoit service, which reads and proccess text files. I wanted the path selection to be from a php based webapp and i wanted a web service to communicate with autoit and get the path name exactly as it is in windows enviroment. PHP is a bit un-friendly and complex with windows paths, so why not play with AutoIT and PHP. The experiement worked and the results are here:

AutoITWSTest.thumb.png.46cf70199a141c792

AutoITWSTest2.thumb.png.e8d4dfbaef7206e0

AutoITWSTest3.thumb.png.c745bc44e10ce556

:-) :-)

Share this post


Link to post
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