matwachich Posted October 5, 2014 Posted October 5, 2014 (edited) 1/ You really need some C and WinAPI basics befor fully understanding DllCall 2/ In windows, always prefere using 'Wide' functions. Nearly all functions that involves strings in/out have 2 variants. See GetUserNameEx, at the end of the msdn page, you have GetUserNameExW (Unicode) and GetUserNameExA (ANSI). The real functions are those 2, and you must know that in modern windows OS (I think XP+) the ...A variant is only a wrapper arround the ...W variant. If you look at the C headers of the WinAPI, you'll see that GetUserNameEx is not really an exported function, but only a preprocessor define that is calling the ...W version when UNICODE is unabled (at compilation time). (And I was very surprised that Calling GetUserNameEx without A or W works fine in AutoIt, I learned something today ) In the same way, about strings data types. TCHAR and TSTR are only defines that are WCHAR (wchar_t) and WSTR (wchar_t*) when UNICODE is unabled, and CHAR (char) and STR (char*) when it is not. (Note: le LP is for long pointer, and the C is for const, sor for example: LPCWSTR = const wchar_t*) I know that all what I say can be very obscure when not knowing C, but remember just to always use ...W functions with W strings. So, the GetUserName function will be: MsgBox(0, "", _GetUserName()) Func _GetUserName() Local $aRet = DllCall("advapi32.dll", "int", "GetUserNameW", "wstr", "", "dword*", 256) If @error Then Return SetError(@error, 0, 0) ; --- ; because the second parameter is a pointer, it is modified by the function ConsoleWrite("User name = " & $aRet[1] & " (" & $aRet[2] & " chars long)" & @CRLF) Return $aRet[1] EndFunc PS: I forgot to mention the main befit of using ...W functions : you will have non-english caracters returned normally. Edited October 5, 2014 by matwachich
jguinch Posted October 5, 2014 Author Posted October 5, 2014 OK, thanks JC. I feel that I will need a lot of practice to begin to stand on my own two feet... Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
jguinch Posted October 5, 2014 Author Posted October 5, 2014 (edited) Hi matwachich ! it's been long time since we did not cross (on the french forum) Sorry, I didn't see your post. Thanks for the great informations, clear enough. For now, I manage to create the following functions : _WinAPI_CreateProfile, _WinAPI_DeleteProfile, _WinAPI_GetAllUsersProfileDirectory, _WinAPI_GetDefaultUserProfileDirectory, _WinAPI_GetProfilesDirectory and _WinAPI_GetProfileType : expandcollapse popup; http://msdn.microsoft.com/en-us/library/windows/desktop/bb762271%28v=vs.85%29.aspx Func _WinAPI_CreateProfile($sUserSid, $sUserName) Local $ret = DllCall("Userenv.dll", "long", "CreateProfile", "wstr", $sUserSid, "wstr", $sUserName, "wstr", "", "dword", 255) If @error Then Return SetError(1, @extended, @error) Return $ret[3] EndFunc ; http://msdn.microsoft.com/en-us/library/windows/desktop/bb762273%28v=vs.85%29.aspx Func _WinAPI_DeleteProfile($sSidString, $sProfilePath, $sComputerName = Null) Local $ret = DllCall("Userenv.dll", "bool", "DeleteProfileW", "wstr", $sSidString, "wstr", $sProfilePath, "wstr", $sComputerName) If @error Then Return SetError(1, @extended, @error) Return $ret[0] EndFunc ; http://msdn.microsoft.com/en-us/library/windows/desktop/bb762276%28v=vs.85%29.aspx Func _WinAPI_GetAllUsersProfileDirectory() Local $ret = DllCall("Userenv.dll", "bool", "GetAllUsersProfileDirectoryW", "wstr", "", "dword*", 255) If @error Then Return SetError(1, @extended, @error) Return $ret[1] EndFunc ; http://msdn.microsoft.com/en-us/library/windows/desktop/bb762277%28v=vs.85%29.aspx Func _WinAPI_GetDefaultUserProfileDirectory() Local $ret = DllCall("Userenv.dll", "bool", "GetDefaultUserProfileDirectoryW", "wstr", "", "dword*", 255) If @error Then Return SetError(1, @extended, @error) Return $ret[1] EndFunc ; http://msdn.microsoft.com/en-us/library/windows/desktop/bb762278%28v=vs.85%29.aspx Func _WinAPI_GetProfilesDirectory() Local $ret = DllCall("Userenv.dll", "bool", "GetProfilesDirectoryW", "wstr", "", "dword*", 255) If @error Then Return SetError(1, @extended, @error) Return $ret[1] EndFunc ; http://msdn.microsoft.com/en-us/library/windows/desktop/bb762279%28v=vs.85%29.aspx Func _WinAPI_GetProfileType() Local $tpdwFlags = DllStructCreate("dword pdwFlags") Local $ppdwFlags = DllStructGetPtr($tpdwFlags) Local $ret = DllCall("Userenv.dll", "bool", "GetProfileType", "ptr", $ppdwFlags ) If @error Then Return SetError(1, @extended, @error) Return DllStructGetData($tpdwFlags, "pdwFlags") EndFunc It seems to be good, but not really sure for _WinAPI_GetProfileType (if someone can give his point of view ?) I have still some questions : the GetProfileType MSDN page says that the returned value can be PT_MANDATORY, PT_ROAMING or PT_TEMPORARY. I cannot find the corresponding values for these 3 possibilities. I had a look one the Shell Constants, Enumerations, and Flags, but they are not described. Where can we find the official information ? Edit : I know these functions are part of AutoIt UDF, but, I wrote this for training (without watching in the UDF source) Edited October 6, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
JohnOne Posted October 5, 2014 Posted October 5, 2014 (edited) Those constants are probably located in Userenv.h header. EDIT: They are #define PT_TEMPORARY 0x00000001 // A profile has been allocated that will be deleted at logoff. #define PT_ROAMING 0x00000002 // The loaded profile is a roaming profile. #define PT_MANDATORY 0x00000004 // The loaded profile is mandatory. Edited October 5, 2014 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
jguinch Posted October 5, 2014 Author Posted October 5, 2014 Good. I thought about an official page, but it seems the #define keyword was what I need. I found the Userenv.h file with CodeBlocks (installed on my computer but not worn out ) Thx ! Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
matwachich Posted October 5, 2014 Posted October 5, 2014 For enumerations and defines, usually an int value type is good. When you don't know/find the value of a constant, google is always you're best friend (as pointed by trancexx). In your DeleteProfile function, last parameter should by wstr. But don't forget to read this from msdn: Note As of Windows Vista, this parameter must be NULL. If it is not, this function fails with the error code ERROR_INVALID_PARAMETER. Last function, I don't understand what you wanted to do It's simple: Const $PT_MANDATORY = 0x00000004 Const $PT_ROAMING = 0x00000002 Const $PT_TEMPORARY = 0x00000001 Func _WinAPI_GetProfileType() Local $ret = DllCall("Userenv.dll", "bool", "GetProfileType", "dword*", 0) If @error Then Return SetError(1, @extended, @error) If $ret[0] Then Return $ret[1] Else Return 0 EndIf End Func PS: Yes, it's been a long time... studies, exams, and soon work!
jguinch Posted October 6, 2014 Author Posted October 6, 2014 OK, I just edited _WinAPI_DeleteProfile (it's a missing : after reading your post about unicode, I changed functions to use unicode, but forgot this parameter). For the last function, I don't know myself what I wanted do to.. In fact, I just get lost with MSDN when it says Pointer to a variable that receives the profile type... Sometime I need to use a pointer, sometime not, even if MSDN talk about pointer... It seems to not want to get into my head ! matwachich 1 Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
matwachich Posted October 6, 2014 Posted October 6, 2014 This is why I talk about some good bases in C and WinAPI. I really think C (not C++) is a master language that every programmer should know, at least variable types and pointers. If you know this, everything will become simple!
Danyfirex Posted October 6, 2014 Posted October 6, 2014 (edited) OK, I just edited _WinAPI_DeleteProfile (it's a missing : after reading your post about unicode, I changed functions to use unicode, but forgot this parameter). For the last function, I don't know myself what I wanted do to.. In fact, I just get lost with MSDN when it says Pointer to a variable that receives the profile type... Sometime I need to use a pointer, sometime not, even if MSDN talk about pointer... It seems to not want to get into my head ! It's because AutoIt work diferent. (to be more easy) msdn say that, because you should pass a variable by reference &Yourvariable (C/C++ way) . it's means your're passing its pointer. So DllCall AutoIt says: Add * to the end of another type to pass it by reference. For example "int*" passes a pointer to an "int" type. AutoIt Does not supports pointers to variables. For that is Dllstructcreate. You can Simulate a variable that can have a reference pointer. Look: Const $PT_MANDATORY = 0x00000004 Const $PT_ROAMING = 0x00000002 Const $PT_TEMPORARY = 0x00000001 Func _WinAPI_GetProfileType() Local $tdword=DllStructCreate("dword") ;Your dword variable Local $pdword=DllStructGetPtr($tdword) ;Your pointer to a dword variable Local $ret = DllCall("Userenv.dll", "bool", "GetProfileType", "ptr", $pdword) If @error Then Return SetError(1, @extended, @error) If $ret[0] Then Return DllStructGetData($tdword,1) Else Return 0 EndIf EndFunc but obviously it's easier, just add *. Saludos Edited October 6, 2014 by Danyfirex Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut
jguinch Posted October 6, 2014 Author Posted October 6, 2014 OK. So my code was good, Danyfirex, no ? matwachich, you're absolutely right : I need some base concepts of C. I will try to find a good website to learn these unavoidable fundamentals. Again, thank you all ! Soon for more questions! Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
Danyfirex Posted October 6, 2014 Posted October 6, 2014 Yes. saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut
matwachich Posted October 6, 2014 Posted October 6, 2014 I learned C here, and the basics of WinAPI here and here. When you got the basics cplusplus.com and msdn are your best friends! mLipok 1
jguinch Posted October 7, 2014 Author Posted October 7, 2014 Cool, thanks. I will try to take the time to read this. Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
AXLE Posted January 1, 2019 Posted January 1, 2019 I know this is an old post, but I couldn't find anything close to topic more recent. When using DLLCall() The Help Document use CAPS the same as Windows API Types, but all examples of DLLCall() seam to use Lower Case. My question is can I use the standard WinAPI Capitols convention for readability, or is there a preference for Lower Case, and if a basic reasoning? Any guidance would be appreciated :-) "Writing code to carry out an intended set of tasks is relatively easy. Writing code to carry out ONLY an intended set of tasks, well that can be a little more challenging." Alex Maddern
Nine Posted January 1, 2019 Posted January 1, 2019 A convention in AutoIt programming is to put all constants in CAPS. That's only a question of readability. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
AXLE Posted January 1, 2019 Posted January 1, 2019 11 minutes ago, Nine said: A convention in AutoIt programming is to put all constants in CAPS. That's only a question of readability. DllCall("user32.dll", "LRESULT", "SendMessageW", "HWND", $idLabel1, "UINT", $iMsg, "WPARAM", 0, "LPARAM", 0) DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $idLabel1, "uint", $iMsg, "wparam", 0, "lparam", 0) The top is how I would go following WIN API Types, The lower seams to the only method in the UDFs. I'll stay with Windows convention as its easier to read. Thanks much for the reply =) "Writing code to carry out an intended set of tasks is relatively easy. Writing code to carry out ONLY an intended set of tasks, well that can be a little more challenging." Alex Maddern
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