SSzretter Posted April 7, 2014 Share Posted April 7, 2014 Specifically, I am using the _WinAPI_CreateFileMapping call, and want to make sure a different user on the same machine is able to receive messages via _WinAPI_OpenFileMapping. I am receiving errors when I try to open the file mapping (invalid handle error #6). I am thinking it's because of the security settings. I found this post, which talks about file mappings and allowing cross user access. The solution was to create a NULL security identifier (not passing null, but passing a valid security identifier, containing null): SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.NullSid, null); The question is, how do I create this in AutoIT, and pass it in to _WinAPI_CreateFileMapping ? Thanks! Link to comment Share on other sites More sharing options...
JohnOne Posted April 7, 2014 Share Posted April 7, 2014 DllStructCreate($tagSECURITY_ATTRIBUTES) AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SSzretter Posted April 7, 2014 Author Share Posted April 7, 2014 Update -- here is some of the code I am using / my attempt to create the security object: Sending script (running as local user): Local $sid = _Security__StringSidToSid("S-1-0") ; also tried S-1-1 $hMapping = _WinAPI_CreateFileMapping(-1, 2048, 'MyFileMapping',0x0004,$sid) ;it seems to accept the sid DllStructSetData($tData, 1, "IDL") ; if($hMapping) send the message... In the receiving service script (running as system account): $hMapping = _WinAPI_OpenFileMapping('MyFileMapping') ; also tried passing read only ,0x0004 - in any case, returns 0x0000 file handle / 0 error 0 extended! ; at one point I was receiving a 1305 error code but I cant seem to duplicate that anymore ; if($hMapping) ... this is how I am trying to receive the message: $pAddress = _WinAPI_MapViewOfFile($hMapping) $tData = DllStructCreate('wchar[1024]', $pAddress) $Text = DllStructGetData($tData, 1) DllStructSetData($tData, 1, '') Link to comment Share on other sites More sharing options...
SSzretter Posted April 7, 2014 Author Share Posted April 7, 2014 Thanks, so I tried this: Local Const $tagSTRUCT1 = "struct;int var1;byte var2;endstruct" Local $sid = DllStructCreate($tagSTRUCT1) DllStructSetData($sid, "var1", 0) ; public enum WellKnownSidType { NullSid = 0 DllStructSetData($sid, "var1", null) I also tried it without the var 2 / null. While it seems to accept this on the sending side, the receiving side is still the same - I cant get a valid handle reference when calling _WinAPI_OpenFileMapping Link to comment Share on other sites More sharing options...
JohnOne Posted April 7, 2014 Share Posted April 7, 2014 So you are just ignoring what I posted? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SSzretter Posted April 7, 2014 Author Share Posted April 7, 2014 So you are just ignoring what I posted? Isn't your suggestion in what I last posted? Link to comment Share on other sites More sharing options...
JohnOne Posted April 7, 2014 Share Posted April 7, 2014 You tell me, it's there for all to see. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SSzretter Posted April 7, 2014 Author Share Posted April 7, 2014 Ok, yes, it is there for 'all' to see, but I will try: You said DllStructCreate($tagSECURITY_ATTRIBUTES) $tagSECURITY_ATTRIBUTES is not defined, so I did a little research and in my post (Today, 08:22 PM) I pasted some code which I believe clearly shows your DllStructCreate(): Local Const $tagSTRUCT1 = "struct;int var1;byte var2;endstruct" Local $sid = DllStructCreate($tagSTRUCT1) SO, maybe I am missing something else you posted (or maybe I just missed the point)? If so, I would greatly appreciate clarification. Thanks for your time! Link to comment Share on other sites More sharing options...
JohnOne Posted April 7, 2014 Share Posted April 7, 2014 You including WinApiEx.au3? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SSzretter Posted April 7, 2014 Author Share Posted April 7, 2014 Actually, no, I was not, so I added that. I have these 3 includes related to WinAPI now: #include <WinAPIFiles.au3> #include <WinAPI.au3> #include <WinApiEx.au3> I tried the 3 different variations above and my receiver is still not getting a valid handle for _WinAPI_OpenFileMapping. The sender is supposedly sending though (no error at least). Also, just to be sure, I added my receiver code inside my sender (using different variable names). I confirmed that I am in fact able to receive the sent message, so I know the sender is working. It seems to be the receiver is not able to get to the file mapping. I also tried running the receiver as a simplified script, running as the user (instead of a service). Interestingly, it was able to open the file mapping, but then the 'DllStructGetData' came back blank (same code that works when I run it in the sender script). So, I am thinking this is still some sort of security setting issue, and I just need to figure out how to set the security attributes in autoit? Link to comment Share on other sites More sharing options...
JohnOne Posted April 7, 2014 Share Posted April 7, 2014 I think it's time you post a full runnable example in code tags. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SSzretter Posted April 8, 2014 Author Share Posted April 8, 2014 Thanks, this is going to be long, but here is the 'receiver' , which is running as a windows service: expandcollapse popup#NoTrayIcon #RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_icon=CHAgent.ico #AutoIt3Wrapper_Compression=4 #AutoIt3Wrapper_Change2CUI=Y #AutoIt3Wrapper_Run_Debug_Mode=Y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;================================================================================ ;;INCLUDES ;;================================================================================ #include <INet.au3> #include <EditConstants.au3> #include <Array.au3> #include <Process.au3> #include <Misc.au3> #include <WinAPIFiles.au3> #include <WinAPI.au3> #include <WinApiEx.au3> #include "services.au3" #include <Constants.au3> #Include <Timers.au3> #include "Startup.au3" ;;================================================================================ ;;Only one occurence can run ;;================================================================================ _Singleton("CHAgentService",0) ;;================================================================================ ;;VARIABLE DEFINITION ;;================================================================================ Dim $MainLog = @TempDir & "\chagentserv.log" Dim $sServiceName = "CHAgentService" $bAU3ServiceDebug=True logprint("script started") If $cmdline[0] > 0 Then Switch $cmdline[1] Case "install", "-i", "/i" InstallService() Case "remove", "-u", "/u", "uninstall" RemoveService() Case Else ConsoleWrite(" - - - Help - - - " & @CRLF) ConsoleWrite("params : " & @CRLF) ConsoleWrite(" -i : install service" & @CRLF) ConsoleWrite(" -u : remove service" & @CRLF) ConsoleWrite(" - - - - - - - - " & @CRLF) Exit EndSwitch Else _Service_init($sServiceName) Exit EndIf Func _main($iArg, $sArgs) If Not _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) Then logprint("Error sending running status, exiting") _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0) Exit EndIf Local $pAddress Local $tData Local $Text Local $hMapping $bServiceRunning = True ; REQUIRED While $bServiceRunning ; REQUIRED ( dont change variable name ) ; there are several ways to find that service have to be stoped - $Running flag in loop is the first method #region --> insert your running code here If $hMapping Then $Text = DllStructGetData($tData, 1) DllStructSetData($tData, 1, '') If $Text Then logprint($Text & @CRLF) Else logprint("no message") EndIf Else ; try to open it *************** THIS IS THE CODE THAT DOES NOT WORK, I RECEIVE error 0, extended 0 and hmapping 0x0000 $hMapping = _WinAPI_OpenFileMapping('MyFileMapping') ;,0x0004 tried this parameter also no difference If Not $hMapping Then logprint("not able to open file mapping!" & "er:" & @error & "ex:" & @extended & "h:" & $hMapping) Else $pAddress = _WinAPI_MapViewOfFile($hMapping) $tData = DllStructCreate('wchar[1024]', $pAddress) EndIf EndIf Sleep (10000) #endregion --> insert your running code here WEnd ; *** CLEANUP (service stop cleanup) _WinAPI_UnmapViewOfFile($pAddress) _WinAPI_CloseHandle($hMapping) _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000) DllCallbackFree($tServiceMain) DllCallbackFree($tServiceCtrl) _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0) DllClose($hAdvapi32_DLL) DllClose($hKernel32_DLL) $bServiceRunning = False; EndFunc ;==>main Func _Sleep($delay) Local $result = DllCall($hKernel32_DLL, "none", "Sleep", "dword", $delay) EndFunc ;==>_Sleep Func logprint($text, $nolog = 0) If $bAU3ServiceDebug Then If Not FileExists($MainLog) Then FileWriteLine($MainLog, "Log created: " & @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC) FileWriteLine($MainLog, @YEAR & @MON & @MDAY & " " & @HOUR & @MIN & @SEC & " [" & @AutoItPID & "] >> " & $text) ConsoleWrite ($text &@CRLF) EndIf Return 0 EndFunc ;==>logprint Func InstallService() If $cmdline[0] > 1 Then $sServiceName = $cmdline[2] EndIf logprint("InstallService("&$sServiceName &"): Installing service, please wait") _Service_Create($sServiceName, $sServiceName, $SERVICE_WIN32_OWN_PROCESS, $SERVICE_AUTO_START, $SERVICE_ERROR_SEVERE, '"' & @ScriptFullPath & '"') If @error Then logprint("InstallService(): Problem installing service, Error number is " & @error & @CRLF & " message : " & _WinAPI_GetLastErrorMessage()) Else logprint("InstallService(): Installation of service successful") _Service_Start($sServiceName) EndIf Exit EndFunc ;==>InstallService Func RemoveService() _Service_Stop($sServiceName) _Service_Delete($sServiceName) If Not @error Then logprint("RemoveService(): service removed successfully" & @CRLF) EndIf Exit EndFunc ;==>RemoveService Func _exit() _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0); EndFunc ;==>_exit Func StopTimer() _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, $iServiceCounter) $iServiceCounter += -100 EndFunc ;==>StopTimer Func _Stopping() _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 3000) EndFunc ;==>_Stopping Here is the 'sender', which is running as background process as the user: expandcollapse popup#NoTrayIcon #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_icon=CHLAgent.ico #AutoIt3Wrapper_Compression=4 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** Opt("mustdeclarevars",1) ;================================================================================ ;;INCLUDES ;;================================================================================ #include <EditConstants.au3> #include <Array.au3> #include <Process.au3> #include <Misc.au3> #include <WinAPIFiles.au3> #include <WinAPI.au3> #include <WinApiEx.au3> #include <Constants.au3> #Include <Timers.au3> ;;================================================================================ ;;Only one occurence can run ;;================================================================================ _Singleton("CHLAgent",0) ;;================================================================================ ;;VARIABLE DEFINITION ;;================================================================================ Global $bAU3ServiceDebug=True logprint("script started") If $cmdline[0] > 0 Then Switch $cmdline[1] Case "install", "-i", "/i" Case "remove", "-u", "/u", "uninstall" Case Else ConsoleWrite(" - - - Help - - - " & @CRLF) ConsoleWrite(" - - - - - - - - " & @CRLF) Exit EndSwitch Else Local $hMapping Local $pAddress Local $tData Local $Text Local $hMapping2 Local $sid = _Security__StringSidToSid("S-1-1") ;Local Const $tagSTRUCT1 = "struct;int var1;byte var2;endstruct" ;Local $sid = DllStructCreate($tagSTRUCT1) ;DllStructSetData($sid, "var1", 0) ; public enum WellKnownSidType { NullSid = 0 ;DllStructSetData($sid, "var2", null) logprint("sid:" & @error) Dim $bServiceRunning = True While $bServiceRunning #region --> insert your running code here If Not $hMapping Then $hMapping = _WinAPI_CreateFileMapping(-1, 2048, 'MyFileMapping',0x0004,$sid) If Not $hMapping Or @extended Then logprint("not able to create file mapping!" & "er:" & @error & "ex:" & @extended) Else $pAddress = _WinAPI_MapViewOfFile($hMapping) $tData = DllStructCreate('wchar[1024]', $pAddress) EndIf Else ; file mapping good, send message If (_Timer_GetIdleTime() > 30000) Then DllStructSetData($tData, 1, "IDL") Else DllStructSetData($tData, 1, "ACT") EndIf logprint("sent message") EndIf ; *** THIS IS TEST CODE TO SEE IF WE CAN RECEIVE IN THE SAME SCRIPT, WHICH YES, WE CAN, THIS WORKS: If $hMapping2 Then $Text = DllStructGetData($tData, 1) DllStructSetData($tData, 1, '') If $Text Then logprint($Text & @CRLF) EndIf Else ; try to open it $hMapping2 = _WinAPI_OpenFileMapping('MyFileMapping') ;,0x0004 If Not $hMapping2 Then logprint("not able to create file mapping!" & "er:" & @error & "ex:" & @extended & "h:" & $hMapping2) Else $pAddress = _WinAPI_MapViewOfFile($hMapping2) $tData = DllStructCreate('wchar[1024]', $pAddress) EndIf EndIf Sleep (10000) #endregion --> insert your running code here WEnd $bServiceRunning = False; _WinAPI_UnmapViewOfFile($pAddress) _WinAPI_CloseHandle($hMapping) Exit EndIf Func _Sleep($delay) Local $result = DllCall($hKernel32_DLL, "none", "Sleep", "dword", $delay) EndFunc ;==>_Sleep Func logprint($text) Dim $MainLog = @TempDir & "\chlagent.log" If $bAU3ServiceDebug Then If Not FileExists($MainLog) Then FileWriteLine($MainLog, "Log created: " & @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC) FileWriteLine($MainLog, @YEAR & @MON & @MDAY & " " & @HOUR & @MIN & @SEC & " [" & @AutoItPID & "] >> " & $text) ConsoleWrite ($text &@CRLF) EndIf Return 0 EndFunc ;==>logprint Link to comment Share on other sites More sharing options...
JohnOne Posted April 8, 2014 Share Posted April 8, 2014 Well I immediately see a problem that the _main function in your receiver is never called. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
BrewManNH Posted April 8, 2014 Share Posted April 8, 2014 What keeps your script running? Everything seems to have an exit in it. I don't see either script as something that starts and then does a couple of functions and then just ends. 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...
SSzretter Posted April 8, 2014 Author Share Posted April 8, 2014 It's a windows service. That part of the script works fine. You will notice all the 'logprint' calls, it writes to a log file, which is how I debug it. That's how I know I am getting an invalid handle, I can see it being logged. SO, to be clear, _main IS being called, it is called by windows when it starts the service. The script stays running because there is a while loop inside main. Link to comment Share on other sites More sharing options...
KaFu Posted April 8, 2014 Share Posted April 8, 2014 (edited) How about something like this? Local $tSecurity = DllStructCreate("int Length;ptr Descriptor;int InheritHandle") ; $tagSECURITY_ATTRIBUTES DllStructSetData($tSecurity, 1, DllStructGetSize($tSecurity)) DllStructSetData($tSecurity, 2, 0) $hMapping = _WinAPI_CreateFileMapping(-1, 2048, 'MyFileMapping',0x0004, DllStructGetPtr($tSecurity)) Edited April 8, 2014 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
SSzretter Posted April 8, 2014 Author Share Posted April 8, 2014 Thanks, that looks promising, but did not work. Same result, no handle (0x0000) in the service. I wish there was a way I could view the activity/permissions - I tried filemon (process monitor) but it does not appear in there. Link to comment Share on other sites More sharing options...
JohnOne Posted April 8, 2014 Share Posted April 8, 2014 (edited) How certain is it that filemapping can be shared between two users? I've used it before between two processes but both the current user. Edited April 8, 2014 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted April 8, 2014 Share Posted April 8, 2014 I believe user script needs SeCreateGlobalPrivilege so #RequireAdmin probably needed to share with service. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SSzretter Posted April 8, 2014 Author Share Posted April 8, 2014 Honestly, I am not sure if it's possible to share between system/user, but I thought it might be possible based on that link in my first post. In that msdn thread, they talk about the 'null' security and it sounds like it's a common issue - by default win32api uses null security which means no one else can access the filemapping. They then explain that you have to create a 'NULL descriptor'. There was mention of the SecurityIdentifier' method, and also ConvertStringSecurityDescriptorToSecurityDescriptor. I am sure you are correct, that require admin would work, but then the user would have to be an Admin / have admin privs, or it will likely cause UAC to keep nagging. I have to avoid that, so I just need a simple way for the two scripts to communicate locally. 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