gdev Posted September 15, 2011 Share Posted September 15, 2011 (edited) Hi, I have found that calling this kernel32 function crashes autoit under some circumstances. I've narrowed it to calling DllCall from a function defined in an AutoIt file, when the main script includes that file and calls that function. Here are the 2 required code files. A third file called "test_details.txt" is also required (it can be empty). File "included.au3" #include-once ; Returns the full path of a given file. ; @see http://msdn.microsoft.com/en-us/library/aa364963%28v=vs.85%29.aspx Func _WinAPI_GetFullPathName( $path ) InputBox( "","Querying", $path ) Local $void = 0 Local $fullPath = "" $res = DllCall( "kernel32.dll", "dword", "GetFullPathName", "str", $path, "dword", 255, "str", $fullPath, "str*", $void ) MsgBox( 0, "Error after Querying", @error ) Return $res[ 3 ] EndFunc $searchPath = @ScriptDir $fileName = "test_details.txt" MsgBox( 0, "Crash test", "This one doesn't crash" ) _WinAPI_GetFullPathName( $searchPath & "\" & $fileName ) File "test.au3" #include <included.au3> MsgBox( 0, "Crash test", "However, calling this will crash" ) _WinAPI_GetFullPathName( @ScriptDir & "\" & "test_details.txt" ) When you run test.au3, the function will be executed once (it is called in included.au3) without a problem. Then, it will be called a second time from test.au3, and it will crash when calling DllCall. I can reproduce this crash on a Windows XP Pro machine, a virtual machine with the same OS and Windows x64 when running AutoIt in 32-bit mode. Under 64-bit mode, my function just crashes all the time. I have reviewed the code several times, and I think it's OK, but I may have missed something that produces this behaviour. However, the AutoIt process should not crash if its a bug in the scripts, so I suspect it's a bug. Edit: removed attached files, replaced by inline code. Edited September 16, 2011 by gdev Link to comment Share on other sites More sharing options...
BrewManNH Posted September 15, 2011 Share Posted September 15, 2011 Doesn't crash for me under Windows 7 x86. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
guinness Posted September 15, 2011 Share Posted September 15, 2011 Have a look at _WinAPI_GetFullPathName in WinAPIEx by Yashied. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
gdev Posted September 15, 2011 Author Share Posted September 15, 2011 Weird... using DllStructCreate('wchar[1024]') works. It's a workaround, but the question of why calling that dll function works in included.au3 and not in test.au3. Link to comment Share on other sites More sharing options...
guinness Posted September 15, 2011 Share Posted September 15, 2011 I didn't test as I always use WinAPIEx or WinAPI when wanting to call API functions and if not included I post a request in WinAPIEx, which has only happened once if I'm honest, wait it was GetFullPathName in fact. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
Yashied Posted September 15, 2011 Share Posted September 15, 2011 Because you wrong use the third parameter in this function. Read carefully MSDN. $File = 'Test.txt' $tPath = DllStructCreate("char[260]") ; MAX_PATH = 260 $Res = DllCall("kernel32.dll", "dword", "GetFullPathNameA", "str", $File, "dword", 260, "ptr", DllStructGetPtr($tPath), "ptr*", 0) ConsoleWrite('Final path: ' & DllStructGetData($tPath, 1) & @CR) ConsoleWrite('Directoty: ' & StringLeft(DllStructGetData($tPath, 1), $Res[4] - DllStructGetPtr($tPath)) & @CR) My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More... Link to comment Share on other sites More sharing options...
gdev Posted September 16, 2011 Author Share Posted September 16, 2011 (edited) LPTSTR lpBuffer = LPWSTR = WCHAR* or = LPSTR = unsigned char* (ANSII) From autoit's help file entry of DllCall: ; Example 2 - calling a function that modifies parameters $result = DllCall("user32.dll", "int", "GetWindowText", "hwnd", $hwnd, "str", "", "int", 32768) msgbox(0, "", $result[0]) ; number of chars returned msgbox(0, "", $result[2]) ; Text returned in param 2 That's why I'm not sending a struct as a parameter. And it works, I get the full path name. It just crashes when I call my custom function from another autoit file. Edited September 16, 2011 by gdev Link to comment Share on other sites More sharing options...
Mat Posted September 16, 2011 Share Posted September 16, 2011 Strings aren't variable length in C If you pass a string of length 0 to be filled with 255 characters then there is going to be a problem. AutoIt Project Listing Link to comment Share on other sites More sharing options...
gdev Posted September 16, 2011 Author Share Posted September 16, 2011 Sure I know that... But I got that from the example... It's passing an empty string as a return (out) parameter. The parameter gets modified by the function and returned in an array by DllCall. And Mat, your answer does not explain why running included.au3 works. Link to comment Share on other sites More sharing options...
trancexx Posted September 16, 2011 Share Posted September 16, 2011 (edited) Strings aren't variable length in C If you pass a string of length 0 to be filled with 255 characters then there is going to be a problem.Mat, what are you talking about? Where is he doing that? The only mistake in your code is the last parameter. Yashied is wrong about you being wrong.The last parameter can receive 0, according to function documentation. That's when it will crash. "str*" is ok to use but not with NULL pointer. edit: and please post this kind of code using code boxes or whatever instead of attaching files. Yes, and when I say please, I mean "do". Edited September 16, 2011 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
gdev Posted September 16, 2011 Author Share Posted September 16, 2011 (edited) Mat, what are you talking about? Where is he doing that? The only mistake in your code is the last parameter. Yashied is wrong about you being wrong.The last parameter can receive 0, according to function documentation. That's when it will crash. "str*" is ok to use but not with NULL pointer. edit: and please post this kind of code using code boxes or whatever instead of attaching files. Yes, and when I say please, I mean "do".Thanks trancexx. That worked in 32-bit mode. I still get a crash (always, no matter which file I run) when running the 64-bit version. Edit: I can't edit the OP, may I paste the code here? Edited September 16, 2011 by gdev Link to comment Share on other sites More sharing options...
trancexx Posted September 16, 2011 Share Posted September 16, 2011 Edit: I can't edit the OP, may I paste the code here?Unless the force would be disturbed. gdev 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
gdev Posted September 16, 2011 Author Share Posted September 16, 2011 Now I can edit, thanks Link to comment Share on other sites More sharing options...
trancexx Posted September 16, 2011 Share Posted September 16, 2011 But where is the code after you changed it the way I told you.You said that you still get crash. With what code? ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
gdev Posted September 16, 2011 Author Share Posted September 16, 2011 Ok, here it is: #include-once ; Returns the full path of a given file. ; @see http://msdn.microsoft.com/en-us/library/aa364963%28v=vs.85%29.aspx Func _WinAPI_GetFullPathName( $path ) InputBox( "","Querying", $path ) Local $void = 0 Local $fullPath = "" $res = DllCall( "kernel32.dll", "dword", "GetFullPathName", "str", $path, "dword", 255, "str", $fullPath, "str*", 0 ) MsgBox( 0, "Error after Querying", @error ) Return $res[ 3 ] EndFunc $searchPath = @ScriptDir $fileName = "test_details.txt" MsgBox( 0, "Crash test", "This one doesn't crash" ) _WinAPI_GetFullPathName( $searchPath & "\" & $fileName ) Link to comment Share on other sites More sharing options...
trancexx Posted September 16, 2011 Share Posted September 16, 2011 Do... not... use... "str*". ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
gdev Posted September 16, 2011 Author Share Posted September 16, 2011 Do... not... use... "str*". Ooops, I forgot about that. Thank you trancexx, it really works now. $res = DllCall( "kernel32.dll", "dword", "GetFullPathName", "str", $path, "dword", 255, "str", $fullPath, "ptr", 0 ) Link to comment Share on other sites More sharing options...
trancexx Posted September 16, 2011 Share Posted September 16, 2011 (edited) Ooops, I forgot about that. Thank you trancexx, it really works now. $res = DllCall( "kernel32.dll", "dword", "GetFullPathName", "str", $path, "dword", 255, "str", $fullPath, "ptr", 0 ) Sure, no problem. Btw, don't forget to water the plants, feed your animals and other stuff. The nature will be grateful. Also, Yashied suggested that MAX_PATH is 260. Edited September 16, 2011 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
gdev Posted September 16, 2011 Author Share Posted September 16, 2011 I'm using 1024 in my application, but more might be needed. The Windows API has many functions that also have Unicode versions to permit an extended-length path for a maximum total path length of 32,767 characters. Link to comment Share on other sites More sharing options...
rover Posted September 17, 2011 Share Posted September 17, 2011 (edited) I'm using 1024 in my application, but more might be needed. Some functions will return the required buffer size, if called with an insufficient buffer. e.g. _WinAPI_MultiByteToWideChar() Or magic numbers are used, like the hated 4096 found in the UDFs. Func _WinAPI_GetFullPathName($sFile) ;modified from WinAPIEx.au3 by Yashied ;In the ANSI version of this function, the name is limited to MAX_PATH characters. ;To extend this limit to 32,767 wide characters, call the Unicode version of the function ;and prepend "\\?\" to the path. ;http://msdn.microsoft.com/en-us/library/aa364963%28v=vs.85%29.aspx ;If the lpBuffer buffer is too small to contain the path, the return value is the size, in TCHARs, ;of the buffer that is required to hold the path and the terminating null character. Local $Ret = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', $sFile, 'dword', 0, 'ptr', 0, 'ptr*', 0) If (@error) Or (Not $Ret[0]) Then Return SetError(1, @error, '') Local $tPath = DllStructCreate('wchar['&$Ret[0]&']') $Ret = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', $sFile, 'dword', $Ret[0], 'ptr', DllStructGetPtr($tPath), 'ptr*', 0) If (@error) Or (Not $Ret[0]) Then Return SetError(2, @error, '') Return DllStructGetData($tPath, 1) EndFunc ;==>_WinAPI_GetFullPathName Edited September 17, 2011 by rover I see fascists... Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now