diff --git a/AddFolderShare.ahk b/AddFolderShare.ahk new file mode 100644 index 0000000..e6aedf6 --- /dev/null +++ b/AddFolderShare.ahk @@ -0,0 +1,69 @@ +#NoTrayIcon +#NoEnv +Process, Priority, , A +#SingleInstance Off +NERR_Success := 0 + +if (!A_IsAdmin) + ExitApp + +; This is the equivalent of "net share 1=C:\1 /GRANT:%USERNAME%,READ /GRANT:%USERNAME%,CHANGE /USERS:2 /CACHE:None" + +userName := A_UserName +shi502_netname := "1" +shi502_path := "C:\1" + +if (DllCall("Netapi32\NetShareCheck", "Ptr", 0, "WStr", shi502_netname, "UInt*", 0) == NERR_Success) ; if this succeeds, it means the folder is already shared + ExitApp + +CSC_MASK_EXT := 0x2030, CSC_CACHE_NONE := 0x0030 +SECURITY_DESCRIPTOR_REVISION := 1, ACL_REVISION := 2 +ACCESS_READ := 0x01, ACCESS_WRITE := 0x02, ACCESS_CREATE := 0x04, ACCESS_EXEC := 0x08, ACCESS_DELETE := 0x10, ACCESS_ATRIB := 0x20 +; thanks to ctusch: https://stackoverflow.com/a/17236838 +FILE_READ_DATA := FILE_LIST_DIRECTORY := 0x1 +FILE_EXECUTE := FILE_TRAVERSE := 0x20 +FILE_WRITE_DATA := FILE_ADD_FILE := 0x2 +FILE_APPEND_DATA := FILE_ADD_SUBDIRECTORY := 0x4 +SHARE_READ := FILE_LIST_DIRECTORY | FILE_READ_EA := 0x8 | FILE_TRAVERSE | FILE_READ_ATTRIBUTES := 0x80 | READ_CONTROL := 0x20000 | SYNCHRONIZE := 0x100000 +SHARE_CHANGE := FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA := 0x10 | FILE_WRITE_ATTRIBUTES := 0x100 | DELETE := 0x10000 +SHARE_FULLCONTROL := FILE_DELETE_CHILD := 0x40 | WRITE_DAC := 0x40000 | WRITE_OWNER := 0x80000 + +; prepare SD with a DACL containing one ACE: your user gets Read and Change access to the share +VarSetCapacity(SecurityDescriptor, 40, 0) +if (!DllCall("advapi32\InitializeSecurityDescriptor", "Ptr", &SecurityDescriptor, "UInt", SECURITY_DESCRIPTOR_REVISION)) + ExitApp +cbAcl := 8 + (12 * 1) ; sizeof(ACL) + ((sizeof(ACCESS_ALLOWED_ACE)) * NUM_OF_ACES) +DllCall("sechost\LookupAccountNameLocalW", "WStr", userName, "Ptr", 0, "UInt*", cbSid := 0, "Ptr", 0, "UInt*", cbDomain := 0, "UInt*", 0) +if (A_LastError != 122) + ExitApp +VarSetCapacity(Sid, cbSid, 0), VarSetCapacity(domain, cbDomain) +if (!DllCall("sechost\LookupAccountNameLocalW", "WStr", userName, "Ptr", &Sid, "UInt*", cbSid, "Ptr", &domain, "UInt*", cbDomain, "UInt*", 0)) + ExitApp +cbAcl += cbSid - 4 ; for (int i = 0; i < NUM_OF_ACES; i++) cbAcl += GetLengthSid(psids[i]) - sizeof(DWORD); // aka: - sizeof(ACE->SidStart) +cbAcl := (cbAcl + (4 - 1)) & 0xfffffffc ; Align cbAcl to a DWORD +if (VarSetCapacity(Acl, cbAcl, 0) != cbAcl) + ExitApp +if (!DllCall("advapi32\InitializeAcl", "Ptr", &Acl, "UInt", cbAcl, "UInt", ACL_REVISION)) + ExitApp +if (!DllCall("advapi32\AddAccessAllowedAce", "Ptr", &Acl, "UInt", ACL_REVISION, "UInt", SHARE_READ | SHARE_CHANGE, "Ptr", &Sid)) + ExitApp +if (!DllCall("advapi32\SetSecurityDescriptorDacl", "Ptr", &SecurityDescriptor, "Int", True, "Ptr", &Acl, "Int", False)) + ExitApp + +; prepare SHARE_INFO_502 struct +VarSetCapacity(SHARE_INFO_502, 72, 0) +NumPut(&shi502_netname, SHARE_INFO_502, 0, "Ptr") +NumPut((shi502_permissions := ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE | ACCESS_EXEC | ACCESS_DELETE | ACCESS_ATRIB), SHARE_INFO_502, 24, "UInt") +NumPut((shi502_max_uses := 2), SHARE_INFO_502, 28, "UInt") +NumPut(&shi502_path, SHARE_INFO_502, 40, "Ptr") +NumPut(&(shi502_passwd := ""), SHARE_INFO_502, 48, "Ptr") +NumPut(&SecurityDescriptor, SHARE_INFO_502, 64, "Ptr") + +if (DllCall("Netapi32\NetShareAdd", "Ptr", 0, "UInt", 502, "Ptr", &SHARE_INFO_502, "Ptr", 0, "UInt") == NERR_Success) { + ; disable caching + if (DllCall("Netapi32\NetShareGetInfo", "Ptr", 0, "WStr", shi502_netname, "UInt", 1005, "Ptr*", SHARE_INFO_1005, "UInt") == NERR_Success) { + NumPut((shi1005_flags := (NumGet(SHARE_INFO_1005+0,, "UInt") & ~CSC_MASK_EXT) | CSC_CACHE_NONE), SHARE_INFO_1005+0,, "UInt") + DllCall("Netapi32\NetShareSetInfo", "Ptr", 0, "WStr", shi502_netname, "UInt", 1005, "Ptr", SHARE_INFO_1005, "Ptr", 0, "UInt") + DllCall("Netapi32\NetApiBufferFree", "Ptr", SHARE_INFO_1005) + } +} \ No newline at end of file diff --git a/AddWindowsInboundFirewallRuleForhttpd.ahk b/AddWindowsInboundFirewallRuleForhttpd.ahk new file mode 100644 index 0000000..deea330 --- /dev/null +++ b/AddWindowsInboundFirewallRuleForhttpd.ahk @@ -0,0 +1,41 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +xammpPath := A_ScriptDir . "\xampp" +httpd := xammpPath . "\apache\bin\httpd.exe" + +if (FileExist(httpd) && A_OSVersion != "WIN_XP" && A_IsAdmin) { + try { + FwPolicy2 := ComObjCreate("HNetCfg.FwPolicy2") + ruleAlreadyExists := False + Rules := FwPolicy2.Rules + for rule in Rules + if (rule.ApplicationName = httpd) { + ruleAlreadyExists := True + break + } + if (!ruleAlreadyExists) { + NewRule := ComObjCreate("HNetCfg.FWRule"), NewRuleUdp := ComObjCreate("HNetCfg.FWRule") + NewRule.Description := NewRule.Name := "httpd.exe" + NewRule.ApplicationName := Format("{:L}", httpd) ; for some reason, the paths are made lower-case by Windows when it adds a firewall rule itself + NewRule.Protocol := NET_FW_IP_PROTOCOL_TCP := 6 + NewRule.RemoteAddresses := NewRule.LocalAddresses := NewRule.RemoteAddresses := NewRule.RemotePorts := "*" + NewRule.Direction := NET_FW_RULE_DIR_IN := 1 + NewRule.InterfaceTypes := "All" + NewRule.Enabled := True + NewRule.Profiles := NET_FW_PROFILE2_PRIVATE := 0x2 | NET_FW_PROFILE2_PUBLIC := 0x4 ; | NET_FW_PROFILE2_DOMAIN := 0x1 / NET_FW_PROFILE2_ALL := 0x7fffffff + NewRule.Action := NET_FW_ACTION_ALLOW := 1 + + NewRuleUdp.Description := NewRuleUdp.Name := NewRule.Name + NewRuleUdp.ApplicationName := NewRule.ApplicationName + NewRuleUdp.Protocol := NET_FW_IP_PROTOCOL_UDP := 17 + NewRuleUdp.RemoteAddresses := NewRuleUdp.LocalAddresses := NewRuleUdp.RemoteAddresses := NewRuleUdp.RemotePorts := NewRule.RemotePorts + NewRuleUdp.Direction := NewRule.Direction + NewRuleUdp.InterfaceTypes := NewRule.InterfaceTypes + NewRuleUdp.Enabled := NewRule.Enabled + NewRuleUdp.Profiles := NewRule.Profiles + NewRuleUdp.Action := NewRule.Action + + Rules.Add(NewRule), Rules.Add(NewRuleUdp) + } + } +} \ No newline at end of file diff --git a/AdvanceToNextSlideshowWallpaper/README.txt b/AdvanceToNextSlideshowWallpaper/README.txt new file mode 100644 index 0000000..159f0e8 --- /dev/null +++ b/AdvanceToNextSlideshowWallpaper/README.txt @@ -0,0 +1,6 @@ +Scripts to advance to next background slideshow picture in the background upon pressing Windows + n + +For Windows 8 and 10, this is a simple affair, thanks to the built-in interface for doing so. + +For Windows 7, this is a different matter entirely. As there is no documented interface for this, this uses ShellContextMenu to display the Desktop right-click menu invisibly in AutoHotkey's process where it selects the "next slideshow background" option. +Far more resource consuming and slower. Because loading a ton of shell DLLs into AutoHotkey brings up the memory usage to at least 20 MB, the Windows 7 script is configured to restart 10 seconds after Windows + n was last pressed. \ No newline at end of file diff --git a/AdvanceToNextSlideshowWallpaper/Windows7.ahk b/AdvanceToNextSlideshowWallpaper/Windows7.ahk new file mode 100644 index 0000000..903a628 --- /dev/null +++ b/AdvanceToNextSlideshowWallpaper/Windows7.ahk @@ -0,0 +1,153 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetBatchLines, -1 +ListLines, Off +#KeyHistory 0 + +#n:: + ShellContextMenu("Desktop", 1) + SetTimer, EmptySet, -10000 +return + +EmptySet: + Run "%A_AhkPath%" /restart "%A_ScriptFullPath%" +return + +; Remake for unicode of Sean's ShellContextMenu by Deo: http://www.autohotkey.com/board/topic/65563-ahk-l-shell-context-menu/ +; ANSI fixes and porting of fragman's additions of directly launching idn and debugging (http://www.autohotkey.com/board/topic/20376-invoking-directly-contextmenu-of-files-and-folders/page-4#entry303574) by qwerty12 +ShellContextMenu(sPath, idn := "", win_hwnd := 0, ShellContextMenuDebug := false) +{ + if (!sPath) + return + pIShellFolder := 0 + pIContextMenu := 0 + idnValid := false + if idn is Integer + idnValid := true + + if (!idnValid && !win_hwnd) { + Gui, SHELL_CONTEXT:New, +hwndwin_hwnd + Gui, Show + } + + if (spath == "Desktop") { + DllCall("shell32\SHGetDesktopFolder", "PtrP", pIShellFolder) + DllCall(VTable(pIShellFolder, 8), "Ptr", pIShellFolder, "Ptr", 0, "Ptr", GUID4String(IID_IContextMenu,"{000214E4-0000-0000-C000-000000000046}"), "PtrP", pIContextMenu) ; CreateViewObject + } else { + If sPath Is Not Integer + DllCall("shell32\SHParseDisplayName", "WStr", A_IsUnicode ? sPath : StrGet(&sPath,, "utf-8"), "Ptr", 0, "PtrP", pidl, "UInt", 0, "UIntP", 0) ;This function is the preferred method to convert a string to a pointer to an item identifier list (PIDL). + Else + DllCall("shell32\SHGetFolderLocation", "Ptr", 0, "Int", sPath, "Ptr", 0, "Uint", 0, "PtrP", pidl) + DllCall("shell32\SHBindToParent", "Ptr", pidl, "Ptr", GUID4String(IID_IShellFolder,"{000214E6-0000-0000-C000-000000000046}"), "PtrP", pIShellFolder, "PtrP", pidlChild) + DllCall(VTable(pIShellFolder, 10), "Ptr", pIShellFolder, "Ptr", 0, "Uint", 1, "Ptr*", pidlChild, "Ptr", GUID4String(IID_IContextMenu,"{000214E4-0000-0000-C000-000000000046}"), "Ptr", 0, "Ptr*", pIContextMenu) ;IShellFolder->GetUIObjectOf + CoTaskMemFree(pidl) + } + ObjRelease(pIShellFolder), pIShellFolder := 0 + + hMenu := DllCall("CreatePopupMenu") + idnMIN := 1 ;idnValid Or debug ? 1 : 3 + ;IContextMenu->QueryContextMenu + ;http://msdn.microsoft.com/en-us/library/bb776097%28v=VS.85%29.aspx + DllCall(VTable(pIContextMenu, 3), "Ptr", pIContextMenu, "Ptr", hMenu, "UInt", 0, "UInt", idnMIN, "UInt", 0x7FFF, "UInt", 0x100) ;CMF_EXTENDEDVERBS + + if (!idnValid) { + ComObjError(0) + global pIContextMenu2 := ComObjQuery(pIContextMenu, IID_IContextMenu2:="{000214F4-0000-0000-C000-000000000046}") + global pIContextMenu3 := ComObjQuery(pIContextMenu, IID_IContextMenu3:="{BCFCE0A0-EC17-11D0-8D10-00A0C90F2719}") + e := A_LastError ;GetLastError() + ComObjError(1) + if (e != 0) + goTo, StopContextMenu + global WPOld := DllCall(A_PtrSize == 8 ? "SetWindowLongPtr" : "SetWindowLong", "Ptr", win_hwnd ? win_hwnd : A_ScriptHwnd, "Int", -4, "Ptr", RegisterCallback("ShellContextMenuWindowProc"), "Ptr") + DllCall("GetCursorPos", "Int64*", pt) + DllCall("InsertMenu", "Ptr", hMenu, "UInt", 0, "UInt", 0x0400|0x800, "Ptr", 2, "Ptr", 0) + DllCall("InsertMenu", "Ptr", hMenu, "UInt", 0, "UInt", 0x0400|0x002, "Ptr", 1, "Ptr", &sPath) + + idn := DllCall("TrackPopupMenuEx", "Ptr", hMenu, "Uint", 0x0100|0x0001, "Int", pt << 32 >> 32, "Int", pt >> 32, "Ptr", win_hwnd ? win_hwnd : A_ScriptHwnd, "Ptr", 0) + } + + /* + typedef struct _CMINVOKECOMMANDINFOEX { + DWORD cbSize; 0 + DWORD fMask; 4 + HWND hwnd; 8 + LPCSTR lpVerb; 8+A_PtrSize + LPCSTR lpParameters; 8+2*A_PtrSize + LPCSTR lpDirectory; 8+3*A_PtrSize + int nShow; 8+4*A_PtrSize + DWORD dwHotKey; 12+4*A_PtrSize + HANDLE hIcon; 16+4*A_PtrSize + LPCSTR lpTitle; 16+5*A_PtrSize + LPCWSTR lpVerbW; 16+6*A_PtrSize + LPCWSTR lpParametersW; 16+7*A_PtrSize + LPCWSTR lpDirectoryW; 16+8*A_PtrSize + LPCWSTR lpTitleW; 16+9*A_PtrSize + POINT ptInvoke; 16+10*A_PtrSize + } CMINVOKECOMMANDINFOEX, *LPCMINVOKECOMMANDINFOEX; + http://msdn.microsoft.com/en-us/library/bb773217%28v=VS.85%29.aspx + */ + struct_size := 16+11*A_PtrSize + VarSetCapacity(pici, struct_size, 0) + NumPut(struct_size, pici, 0, "Uint") ;cbSize + NumPut((A_IsUnicode ? 0x00004000 : 0) | 0x20000000 | 0x00100000, pici, 4, "UInt") ;fMask + NumPut(win_hwnd ? win_hwnd : A_ScriptHwnd, pici, 8, "UPtr") ;hwnd + NumPut(1, pici, 8+4*A_PtrSize, "Uint") ;nShow + NumPut(idn-idnMIN, pici, 8+A_PtrSize, "UPtr") ;lpVerb + if (A_IsUnicode) + NumPut(idn-idnMIN, pici, 16+6*A_PtrSize, "UPtr") ;lpVerbW + if (!idnValid) + NumPut(pt, pici, 16+10*A_PtrSize, "UPtr") ;ptInvoke + + DllCall(VTable(pIContextMenu, 4), "Ptr", pIContextMenu, "Ptr", &pici) ; InvokeCommand + + if (!idnValid) { + if (ShellContextMenuDebug) { + VarSetCapacity(sName, 522) + DllCall(VTable(pIContextMenu, 5), "Ptr", pIContextMenu, "UInt", idn-idnMIN, "UInt", 0x00000000, "UIntP", 0, "Str", sName, "Uint", 260) ; GetCommandString + if (A_IsUnicode) + sName := StrGet(&sName,, "utf-8") + OutputDebug, idn: %idn% command string: %sName% + } + DllCall("GlobalFree", "Ptr", DllCall("SetWindowLongPtr", "Ptr", win_hwnd ? win_hwnd : A_ScriptHwnd, "Int", -4, "Ptr", WPOld, "UPtr")) + } +StopContextMenu: + DllCall("DestroyMenu", "Ptr", hMenu) + if (!idnValid) { + ObjRelease(pIContextMenu3), ObjRelease(pIContextMenu2) + pIContextMenu3 := pIContextMenu2 := WPOld := 0 + } + ObjRelease(pIContextMenu), pIContextMenu := 0 + Gui, SHELL_CONTEXT:Destroy + VarSetCapacity(pici, 0) + return idn +} + +ShellContextMenuWindowProc(hWnd, nMsg, wParam, lParam) +{ + Global pIContextMenu2, pIContextMenu3, WPOld + If pIContextMenu3 { ;IContextMenu3->HandleMenuMsg2 + If !DllCall(VTable(pIContextMenu3, 7), "Ptr", pIContextMenu3, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam, "Ptr*", lResult) + return lResult + } + Else If pIContextMenu2 { ;IContextMenu2->HandleMenuMsg + If !DllCall(VTable(pIContextMenu2, 6), "Ptr", pIContextMenu2, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam) + return 0 + } + return DllCall("user32.dll\CallWindowProcW", "Ptr", WPOld, "Ptr", hWnd, "Uint", nMsg, "Ptr", wParam, "Ptr", lParam) +} + +VTable(ppv, idx) +{ + Return NumGet(NumGet(ppv+0)+A_PtrSize*idx) +} + +GUID4String(ByRef CLSID, String) +{ + VarSetCapacity(CLSID, 16, 0) + return DllCall("ole32\CLSIDFromString", "WStr", String, "Ptr", &CLSID) >= 0 ? &CLSID : "" +} + +CoTaskMemFree(pv) +{ + return DllCall("ole32\CoTaskMemFree", "Ptr", pv) +} diff --git a/AdvanceToNextSlideshowWallpaper/Windows8and10.ahk b/AdvanceToNextSlideshowWallpaper/Windows8and10.ahk new file mode 100644 index 0000000..5345baa --- /dev/null +++ b/AdvanceToNextSlideshowWallpaper/Windows8and10.ahk @@ -0,0 +1,9 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +#n:: + if (pDesktopWallpaper && DllCall(NumGet(NumGet(pDesktopWallpaper+0)+16*A_PtrSize), "Ptr", pDesktopWallpaper, "Ptr", 0, "UInt", 0) != -2147023174) ; IDesktopWallpaper::AdvanceSlideshow - https://msdn.microsoft.com/en-us/library/windows/desktop/hh706947(v=vs.85).aspx + return + ObjRelease(pDesktopWallpaper) + if ((pDesktopWallpaper := ComObjCreate("{C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD}", "{B92B56A9-8B55-4E14-9A89-0199BBB6F93B}"))) + goto %A_ThisHotkey% +return \ No newline at end of file diff --git a/BeepWhenPrintJobAddedForDefaultPrinter.ahk b/BeepWhenPrintJobAddedForDefaultPrinter.ahk new file mode 100644 index 0000000..4a4c80d --- /dev/null +++ b/BeepWhenPrintJobAddedForDefaultPrinter.ahk @@ -0,0 +1,51 @@ +#NoEnv +PRINTER_CHANGE_ADD_JOB := 0x00000100 ; FindFirstPrinterChangeNotification +INVALID_HANDLE_VALUE := -1 + +; MsgWaitForMultipleObjectsEx constants: +WAIT_OBJECT_0 := 0x00000000, WAIT_FAILED := INFINITE := 0xFFFFFFFF, MWMO_ALERTABLE := 0x0002, MWMO_INPUTAVAILABLE := 0x0004 +QS_INPUT := (QS_MOUSE := (QS_MOUSEMOVE := 0x0002 | QS_MOUSEBUTTON := 0x0004)) | QS_KEY := 0x0001 | QS_RAWINPUT := 0x0400 ; QS_TOUCH and QS_POINTER are included on Windows 8+ AFAIK in WinUser.h +QS_ALLINPUT := QS_INPUT | QS_POSTMESSAGE := 0x0008 | QS_TIMER := 0x0010 | QS_PAINT := 0x0020 | QS_HOTKEY := 0x0080 | QS_SENDMESSAGE := 0x0040 + +hModWinspool := DllCall("LoadLibrary", "Str", "winspool.drv", "Ptr") + +; Get default printer name +if (DllCall("winspool.drv\GetDefaultPrinter", "Ptr", 0, "UInt*", cchDefPrinter)) + ExitApp 1 +VarSetCapacity(defaultPrinterName, cchDefPrinter * (A_IsUnicode + 1)) +DllCall("winspool.drv\GetDefaultPrinter", "Ptr", &defaultPrinterName, "UInt*", cchDefPrinter) + +if (!DllCall("winspool.drv\OpenPrinter", "Ptr", &defaultPrinterName, "Ptr*", hDefaultPrinter, "Ptr", 0)) + ExitApp 1 +OnExit("cleanup") + +if ((hDefaultPrinterChange := DllCall("winspool.drv\FindFirstPrinterChangeNotification", "Ptr", hDefaultPrinter, "UInt", PRINTER_CHANGE_ADD_JOB, "UInt", PRINTER_NOTIFY_CATEGORY_2D := 0x000000, "Ptr", 0, "Ptr")) == INVALID_HANDLE_VALUE) + ExitApp 1 + +bKeepMonitoring := True +while (bKeepMonitoring) { + ; Bastardised from Lexikos' FileExtract + r := DllCall("MsgWaitForMultipleObjectsEx", "UInt", 1, "Ptr*", hDefaultPrinterChange, "UInt", INFINITE, "UInt", QS_ALLINPUT, "UInt", MWMO_ALERTABLE | MWMO_INPUTAVAILABLE, "UInt"), Sleep 0 + if (!bKeepMonitoring || r == WAIT_FAILED) { + break + } else if (r == WAIT_OBJECT_0) { + if ((DllCall("winspool.drv\FindNextPrinterChangeNotification", "Ptr", hDefaultPrinterChange, "UInt*", dwChange, "Ptr", 0, "Ptr", 0)) && dwChange & PRINTER_CHANGE_ADD_JOB) + SoundBeep ; replace this for something stronger + } +} + +cleanup() +{ + global watchPrinter, hDefaultPrinter, hDefaultPrinterChange, hModWinspool, bKeepMonitoring, INVALID_HANDLE_VALUE + ;Critical On + bKeepMonitoring := False + ;PostMessage, 0x0000,,,, ahk_id %A_ScriptHwnd% + ;Sleep -1 + if (hDefaultPrinterChange != INVALID_HANDLE_VALUE) + DllCall("winspool.drv\FindClosePrinterChangeNotification", "Ptr", hDefaultPrinterChange), hDefaultPrinterChange := INVALID_HANDLE_VALUE + if (hDefaultPrinter) + DllCall("winspool.drv\ClosePrinter", "Ptr", hDefaultPrinter), hDefaultPrinter := 0 + if (hModWinspool) + DllCall("FreeLibrary", "Ptr", hModWinspool), hModWinspool := 0 + ;Critical Off +} \ No newline at end of file diff --git a/CreateHardlinksFromSelectedExplorerFiles/CreateHardlinksFromSelectedExplorerFiles.ahk b/CreateHardlinksFromSelectedExplorerFiles/CreateHardlinksFromSelectedExplorerFiles.ahk new file mode 100644 index 0000000..dc69a1b --- /dev/null +++ b/CreateHardlinksFromSelectedExplorerFiles/CreateHardlinksFromSelectedExplorerFiles.ahk @@ -0,0 +1,153 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +; #Warn ; Enable warnings to assist with detecting common errors. +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. +#SingleInstance Force + +; apparently not needed for hard links +/* +; From AutoHotkey's Process docpage +Process, Exist ; sets ErrorLevel to the PID of this running script +; Get the handle of this script with PROCESS_QUERY_INFORMATION (0x0400) +h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel, "Ptr") +; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32) +DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "PtrP", t) +VarSetCapacity(ti, 16, 0) ; structure of privileges +NumPut(1, ti, 0, "UInt") ; one entry in the privileges array... +; Retrieves the locally unique identifier of the debug privilege: +DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeCreateSymbolicLinkPrivilege", "Int64P", luid) +NumPut(luid, ti, 4, "Int64") +NumPut(2, ti, 12, "UInt") ; enable this privilege: SE_PRIVILEGE_ENABLED = 2 +; Update the privileges of this process with the new access token: +r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", &ti, "UInt", 0, "Ptr", 0, "Ptr", 0) +DllCall("CloseHandle", "Ptr", t) ; close this access token handle to save memory +DllCall("CloseHandle", "Ptr", h) ; close this process handle to save memory +*/ + +#If ((expWnd := validExplorerWindow(WinExist("A"), expWndType))) +^+c:: +hardLinkSourceFiles := getExplorerSelectedFiles(expWnd, expWndType) +if ((hardlinkSourceCount := hardLinkSourceFiles.MaxIndex())) + TrayTip,, % hardlinkSourceCount . (hardlinkSourceCount == 1 ? " file" : " files") . " selected for hard linking" +return + +^+v:: +if ((hardLinkSourceFiles.MaxIndex()) && (expPath := getExplorerWindowPath(expWnd, expWndType))) { + expPath .= "\" + for idx, file in hardLinkSourceFiles + if (!DllCall("CreateHardLink", "Str", expPath . file.Name, "Str", file.Path, "Ptr", 0)) + hardLinkSourceFiles.RemoveAt(idx) + selectFilesInFolder(expWnd, expWndType, hardLinkSourceFiles) + hardLinkSourceFiles := "" +} +#If +return + +validExplorerWindow(hwnd, ByRef outType) +{ + outType := 0 + if (hwnd) { + WinGetClass wndClass, ahk_id %hwnd% + if (wndClass == "CabinetWClass") + outType := 1 + else if (wndClass == "Progman" || wndClass == "WorkerW") + outType := 2 + + if (outType) + return hwnd + } + return 0 +} + +getExplorerWindowPath(hwnd, hwndType) +{ + ; qwerty12's https://autohotkey.com/boards/viewtopic.php?f=5&t=31135 + static IID_IShellFolder, STRRET, path, SIGDN_FILESYSPATH := 0x80058000 + if (!VarSetCapacity(IID_IShellFolder)) + VarSetCapacity(IID_IShellFolder, 16), DllCall("ole32\CLSIDFromString", "WStr", "{000214E6-0000-0000-C000-000000000046}", "Ptr", &IID_IShellFolder) + ,VarSetCapacity(STRRET, 272), VarSetCapacity(path, 262 * (!!A_IsUnicode + 1)) + + if (hwndType == 2) + return A_Desktop + else if (hwndType == 1) { + shellWindows := ComObjCreate("Shell.Application").Windows + for window in shellWindows { + if (window.hwnd == hwnd) { + try { + isp := ComObjQuery(window, "{6d5140c1-7436-11ce-8034-00aa006009fa}") + tlb := ComObjQuery(isp, "{4C96BE40-915C-11CF-99D3-00AA004AE837}", "{000214E2-0000-0000-C000-000000000046}") + if (DllCall(NumGet(NumGet(tlb+0)+15*A_PtrSize), "Ptr", tlb, "Ptr*", isv) < 0) + throw + ifv := ComObjQuery(isv, "{cde725b0-ccc9-4519-917e-325d72fab4ce}") + if (DllCall(NumGet(NumGet(ifv+0)+5*A_PtrSize), "Ptr", ifv, "Ptr", &IID_IShellFolder, "Ptr*", isf) < 0) + throw + if (DllCall(NumGet(NumGet(isf+0)+11*A_PtrSize), "Ptr", isf, "Ptr", 0, "UInt", SIGDN_FILESYSPATH, "Ptr", &STRRET) < 0) + throw + if (DllCall("shlwapi\StrRetToBuf", "Ptr", &STRRET, "Ptr", 0, "Str", path, "UInt", 260)) + throw + return path + } catch { + return 0 + } finally { + for _, obj in [isf, ifv, isv, tlb, isp] + if (obj) + ObjRelease(obj) + } + } + } + } + + return 0 +} + +getExplorerSelectedFiles(hwnd, hwndType) +{ + ret := 0 + + items := getFolderDocument(hwnd, hwndType).SelectedItems + + if (items.Count) { + ret := [] + for Item in items + if (!Item.IsFolder) ; you can't hardlink folders + ret.push({Path: Item.Path, Name: Item.Name}) + } + + return ret +} + +getFolderDocument(hwnd, hwndType) +{ + ;Based on Rapte_of_Suzaku's https://autohotkey.com/board/topic/60985-get-paths-of-selected-items-in-an-explorer-window/ and Lexikos' https://autohotkey.com/boards/viewtopic.php?t=9618 + static _hwnd + Document := 0 + shellWindows := ComObjCreate("Shell.Application").Windows + + if (hwndType == 1) { + for window in shellWindows { + if (window.hwnd == hwnd) { + Document := window.Document + break + } + } + } else if (hwndType == 2) { + if (!VarSetCapacity(_hwnd)) + VarSetCapacity(_hwnd, 4, 0) + desktop := shellWindows.FindWindowSW(0, "", 8, ComObj(0x4003, &_hwnd), 1) + Document := desktop.Document + } + + return Document +} + +selectFilesInFolder(hwnd, hwndType, namesOfFiles) +{ + ; Based on Lexikos' https://autohotkey.com/boards/viewtopic.php?t=9618 + + Document := getFolderDocument(hwnd, hwndType) + items := Document.SelectedItems + Loop % items.Count + Document.SelectItem(items.Item(A_Index-1), 0) + for _, file in namesOfFiles + Document.SelectItem(items.Item(file.Name), 1) +} \ No newline at end of file diff --git a/CreateHardlinksFromSelectedExplorerFiles/README.txt b/CreateHardlinksFromSelectedExplorerFiles/README.txt new file mode 100644 index 0000000..f18a8ee --- /dev/null +++ b/CreateHardlinksFromSelectedExplorerFiles/README.txt @@ -0,0 +1,2 @@ +* Select files in an open Explorer window, press Ctrl + Shift + C +* Open your destination window and press Ctrl + Shift + V to have hardlinks of your files placed there \ No newline at end of file diff --git a/GetPotPlayer64CurrentPlayingFilePath.ahk b/GetPotPlayer64CurrentPlayingFilePath.ahk new file mode 100644 index 0000000..1f98aed --- /dev/null +++ b/GetPotPlayer64CurrentPlayingFilePath.ahk @@ -0,0 +1,77 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +; Play a file in PotPlayer and press q at the window +; Credits: +; * The Old New Thing & Lexikos for the MsgWaitForMultipleObjectsEx code +; * http://cafe.daum.net/pot-tool/N88T/65 for providing an English version of the SDK + +class PotPlayerCurrentFile +{ + static _WM_COPYDATA := 0x004A, _POT_COMMAND := _WM_USER := 0x0400, _POT_GET_PLAYFILE_NAME := 0x6020 + + GetFullPath(hwnd, dwTimeout) + { + static MsgWaitForMultipleObjectsEx := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "user32.dll", "Ptr"), "AStr", "MsgWaitForMultipleObjectsEx", "Ptr") + fn := "" + + WinGetClass, clazz, ahk_id %hwnd% + if (InStr(clazz, "PotPlayer")) { + r := 0xFFFFFFFF + ,this.hEvent := DllCall("CreateEvent", "Ptr", 0, "Int", True, "Int", False, "Ptr", 0, "Ptr") + ,this.potPlayerHwnd := hwnd + ,this.cdReceiver := ObjBindMethod(this, "_On_WM_COPYDATA") + ,OnMessage(this._WM_COPYDATA, this.cdReceiver, -1) + + if (this._MessagePotPlayer(dwTimeout)) { + dwStart := A_TickCount + while ((dwElapsed := A_TickCount - dwStart) < dwTimeout) { + r := DllCall(MsgWaitForMultipleObjectsEx, "UInt", 1, "Ptr*", this.hEvent, "UInt", dwTimeout - dwElapsed, "UInt", 0x4FF, "UInt", 0x4, "UInt") + if (r == 0 || r == 0xFFFFFFFF || r == 258) + break + Sleep -1 + } + ;OutputDebug % A_ThisFunc . ": " . (A_TickCount - dwStart) . " milliseconds have elapsed" + } + + OnMessage(this._WM_COPYDATA, this.cdReceiver, 0) ,this.cdReceiver := "" + ,DllCall("CloseHandle", "Ptr", this.hEvent), this.hEvent := 0 + if (r == 0) + fn := this.PotPlayerFilename + } + + this := "" + return fn + } + + _MessagePotPlayer(ByRef Timeout := 5000) + { + Critical On + ;dwStart := A_TickCount + PostMessage, % this._POT_COMMAND, % this._POT_GET_PLAYFILE_NAME, %A_ScriptHwnd%,, % "ahk_id " . this.potPlayerHwnd,,,, %Timeout% + ;Timeout -= A_TickCount - dwStart + ret := ErrorLevel == 0 + Critical Off + return ret + } + + _On_WM_COPYDATA(wParam, lParam, msg, hwnd) + { + if (lParam && hwnd == A_ScriptHwnd && wParam == this.potPlayerHwnd && NumGet(lParam+0,, "UPtr") == this._POT_GET_PLAYFILE_NAME) { + StringLength := NumGet(lParam+0, A_PtrSize, "UInt") + ,StringAddress := NumGet(lParam+0, 2*A_PtrSize, "Ptr") + ,this.PotPlayerFilename := StrGet(StringAddress, StringLength, "UTF-8") + ,DllCall("SetEvent", "Ptr", this.hEvent) + return True + } + return False + } +} + +PotPlayer64_GetCurrentFilePath(hwnd, replyTimeout := 1100) +{ + return PotPlayerCurrentFile.GetFullPath(hwnd, replyTimeout) +} + +#If ((hwnd := WinActive("ahk_class PotPlayer64"))) +q::MsgBox % PotPlayer64_GetCurrentFilePath(hwnd) +#If \ No newline at end of file diff --git a/GetResultsFromEverythingSearch.ahk b/GetResultsFromEverythingSearch.ahk new file mode 100644 index 0000000..888feca --- /dev/null +++ b/GetResultsFromEverythingSearch.ahk @@ -0,0 +1,12 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +; Copy of https://www.voidtools.com/support/everything/sdk/c/ +; Place Everything32.dll and Everything64.dll from the SDK (https://www.voidtools.com/downloads/) into the same directory as this script +EverythingDll := "Everything" . (A_PtrSize == 8 ? "64" : "32") . ".dll" +EverythingMod := DllCall("LoadLibrary", "Str", A_ScriptDir . "\" . EverythingDll, "Ptr") +DllCall(EverythingDll . "\Everything_SetSearch", "Str", "Taskmgr.exe") +DllCall(EverythingDll . "\Everything_Query", "Int", True) +Loop % DllCall(EverythingDll . "\Everything_GetNumResults", "UInt") + MsgBox % DllCall(EverythingDll . "\Everything_GetResultFileName", "UInt", A_Index - 1, "Str") . " [" . DllCall(EverythingDll . "\Everything_GetResultPath", "UInt", A_Index - 1, "Str") . "]" +DllCall(EverythingDll . "\Everything_Reset") +DllCall("FreeLibrary", "Ptr", EverythingMod) \ No newline at end of file diff --git a/GetTaskbarVisibleWindows.ahk b/GetTaskbarVisibleWindows.ahk new file mode 100644 index 0000000..fd5fb7b --- /dev/null +++ b/GetTaskbarVisibleWindows.ahk @@ -0,0 +1,181 @@ +#NoEnv +#Include + +if (A_ScriptName == "GetTaskbarVisibleWindows.ahk") { + Menu, Tray, NoIcon + SetBatchLines -1 + ListLines, Off + for _, hwnd in GetTaskbarVisibleWindows() { + WinGetClass wndClass, ahk_id %hwnd% + WinGetTitle wndTitle, ahk_id %hwnd% + x .= wndClass . " - " . (wndTitle ? wndTitle : Format("{:x}", hwnd)) . "`n" + /* ScClose("ahk_id " . hwnd) + */ + } + MsgBox % x + ExitApp +} + +; Based off code from the following projects: +; * https://sourceforge.net/projects/taskswitchxp/ +; * https://github.com/kvakulo/Switcheroo + +GetTaskbarVisibleWindows(limit:=0, checkDisabled:=True, checkEmptyTitle:=False + ,checkNoActivate:=True, checkImmediateOwnerVisibility:=True + ,checkITaskListDeleted:=True, useAudioRouterAlgo:=True) +{ + static sevenOrBelow := A_OSVersion ~= "WIN_(7|XP|VISTA)", rect, PropEnumProcEx := 0, cleanup := {base: {__Delete: "GetTaskbarVisibleWindows"}} + static WS_DISABLED := 0x08000000, WS_EX_TOOLWINDOW := 0x00000080, WS_EX_APPWINDOW := 0x00040000, WS_EX_CONTROLPARENT := 0x00010000, WS_EX_NOREDIRECTIONBITMAP := 0x00200000, WS_EX_NOACTIVATE := 0x08000000 + static GA_ROOTOWNER := 3, GW_OWNER := 4, DWMWA_CLOAKED := 14 + + if (PropEnumProcEx && A_EventInfo == PropEnumProcEx && checkNoActivate >= 4096 && IsWindow(limit)) { + if (checkDisabled && StrGet(checkDisabled) == "ApplicationViewCloakType") { + NumPut(checkEmptyTitle != 1, checkNoActivate+0, "Int") + return False + } + return True + } + + if (!cleanup) { + if (PropEnumProcEx) + DllCall("GlobalFree", "Ptr", PropEnumProcEx, "Ptr"), PropEnumProcEx := 0 + return + } + + if (!VarSetCapacity(rect)) { + VarSetCapacity(rect, 16) + if (!sevenOrBelow) + PropEnumProcEx := RegisterCallback(A_ThisFunc, "Fast", 4) + } + + shell := 0 ; DllCall("GetShellWindow", "Ptr") + + ret := [] + prevDetectHiddenWindows := A_DetectHiddenWindows + + DetectHiddenWindows Off + + WinGet id, list,,, Program Manager + Loop %id% { + hwnd := id%A_Index% + + if (limit && limit == ret.MaxIndex()) + break + + if (checkEmptyTitle) { + WinGetTitle wndTitle, ahk_id %hwnd% + if (!wndTitle) + continue + } + + if (checkDisabled) { + WinGet dwStyle, Style, ahk_id %hwnd% + if (dwStyle & WS_DISABLED) + continue + } + + if (checkITaskListDeleted && DllCall("GetProp", "Ptr", hwnd, "Str", "ITaskList_Deleted", "Ptr")) + continue + + if (DllCall("GetWindowRect", "Ptr", hwnd, "Ptr", &rect) && !DllCall("IsRectEmpty", "Ptr", &rect)) { + if (!shell) { + hwndRootOwner := DllCall("GetAncestor", "Ptr", hwnd, "UInt", GA_ROOTOWNER, "Ptr") + } else { + hwndTmp := hwnd + Loop { + hwndRootOwner := hwndTmp + hwndTmp := DllCall("GetWindow", "Ptr", hwndTmp, "UInt", GW_OWNER, "Ptr") + } until (!hwndTmp || hwndTmp == shell) + } + + WinGet dwStyleEx, ExStyle, ahk_id %hwndRootOwner% + if (hwnd != hwndRootOwner) + WinGet dwStyleEx2, ExStyle, ahk_id %hwnd% + else + dwStyleEx2 := dwStyleEx + + hasAppWindow := dwStyleEx2 & WS_EX_APPWINDOW + if (checkNoActivate) + if ((dwStyleEx2 & WS_EX_NOACTIVATE) && !hasAppWindow) + continue + + if (checkImmediateOwnerVisibility) { + hwndOwner := DllCall("GetWindow", "Ptr", hwnd, "UInt", GW_OWNER, "Ptr") + if (!(!hwndOwner || !DllCall("IsWindowVisible", "Ptr", hwndRootOwner))) + continue + } + + if (!(dwStyleEx & WS_EX_TOOLWINDOW) || hasAppWindow || (!(dwStyleEx2 & WS_EX_TOOLWINDOW) && dwStyleEx2 & WS_EX_CONTROLPARENT)) { + if (useAudioRouterAlgo && !is_main_window(hwnd)) + continue + if (!sevenOrBelow) { + WinGetClass wndClass, ahk_id %hwnd% + if (wndClass == "Windows.UI.Core.CoreWindow") + continue + if (wndClass == "ApplicationFrameWindow") { + hasAppropriateApplicationViewCloakType := !PropEnumProcEx + if (PropEnumProcEx) + DllCall("EnumPropsEx", "Ptr", hwnd, "Ptr", PropEnumProcEx, "Ptr", &hasAppropriateApplicationViewCloakType) + if (!hasAppropriateApplicationViewCloakType) + continue + } else { + if (dwStyleEx & WS_EX_NOREDIRECTIONBITMAP) + continue + if (!DllCall("dwmapi\DwmGetWindowAttribute", "Ptr", hwndRootOwner, "UInt", DWMWA_CLOAKED, "UInt*", isCloaked, "Ptr", 4) && isCloaked) + continue + } + } + ret.push(hwnd) + } + } + } + + DetectHiddenWindows %prevDetectHiddenWindows% + return ret +} + +; Based off https://github.com/audiorouterdev/audio-router +is_main_window(handle) +{ + static WS_CHILD := 0x40000000, WS_OVERLAPPED := 0x00000000, WS_POPUP := 0x80000000 + static WS_EX_WINDOWEDGE := 0x00000100, WS_EX_CLIENTEDGE := 0x00000200, WS_EX_DLGMODALFRAME := 0x00000001, WS_EX_OVERLAPPEDWINDOW := WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE + WinGet Style, Style, ahk_id %handle% + WinGet Style, ExStyle, ahk_id %handle% + + if (Style & WS_CHILD) + return FALSE + + i := 0 + if(Style & WS_OVERLAPPED) + i++ + if(Style & WS_POPUP) + { + i-- + if(DllCall("GetParent", "Ptr", handle)) + i-- + } + if(ExStyle & WS_EX_OVERLAPPEDWINDOW) + i++ + if(ExStyle & WS_EX_CLIENTEDGE) + i-- + if(ExStyle & WS_EX_DLGMODALFRAME) + i-- + return (i >= 0) +} + +; Based off https://stackoverflow.com/a/4688414 +GetTaskbarVisibleWindows_IsWindowVisible(m_hWnd) +{ + static GetWindowRect := PopupMenuUtils_user32_handle("GetWindowRect"), rgn := 0, rtView, RectInRegion := DllCall("GetProcAddress", Ptr, DllCall("GetModuleHandle", Str, "gdi32.dll", "Ptr"), AStr, "RectInRegion", "Ptr"), cleanup := {base: {__Delete: "GetTaskbarVisibleWindows_IsWindowVisible"}} + + if (!cleanup) { + if (rgn) + DllCall("Gdi32\DeleteObject", "Ptr", rgn), rgn := 0 + return + } + + if (!rgn) + VarSetCapacity(rtView, 16), VarSetCapacity(rtDesktop, 16), DllCall(GetWindowRect, "Ptr", DllCall("GetDesktopWindow", "Ptr"), "Ptr", &rtDesktop), rgn := DllCall("Gdi32\CreateRectRgn", "Int", NumGet(rtDesktop, 0, "Int"), "Int", NumGet(rtDesktop, 4, "Int"), "Int", NumGet(rtDesktop, 8, "Int"), "Int", NumGet(rtDesktop, 12, "Int"), "Ptr") + + return DllCall(GetWindowRect, "Ptr", m_hWnd, "Ptr", &rtView) && DllCall(RectInRegion, "Ptr", rgn, "Ptr", &rtView) +} diff --git a/GetWindowsMediaPlayerPlayState/GetWindowsMediaPlayerPlayState.ahk b/GetWindowsMediaPlayerPlayState/GetWindowsMediaPlayerPlayState.ahk new file mode 100644 index 0000000..feea905 --- /dev/null +++ b/GetWindowsMediaPlayerPlayState/GetWindowsMediaPlayerPlayState.ahk @@ -0,0 +1,199 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +#SingleInstance Off + +Process, Exist, wmplayer.exe +if (!ErrorLevel) { + MsgBox Run Windows Media Player first. Exiting + ExitApp +} + +wmp := ComObjCreate("WMPlayer.OCX") + +rms := IWMPRemoteMediaServices_CreateInstance() +ocs := ComObjQuery(rms, "{00000118-0000-0000-C000-000000000046}") + +ole := ComObjQuery(wmp, "{00000112-0000-0000-C000-000000000046}") +DllCall(NumGet(NumGet(ole+0)+3*A_PtrSize), "Ptr", ole, "Ptr", ocs) + +states := {0: "Undefined", 1: "Stopped", 2: "Paused", 3: "Playing"} +state := states[wmp.playState] + +DllCall(NumGet(NumGet(ole+0)+3*A_PtrSize), "Ptr", ole, "Ptr", 0) +for _, obj in [ole, ocs, rms] + ObjRelease(obj) +wmp := "" + +MsgBox %state% + +; --- + +IWMPRemoteMediaServices_CreateInstance() +{ + global IWMPRemoteMediaServices_size := ((A_PtrSize + 4) * 4) + 4 + static vtblUnk, vtblRms, vtblIsp, vtblOls + , vtblPtrs := 0 + + if (!VarSetCapacity(vtblUnk)) { + extfuncs := ["QueryInterface", "AddRef", "Release"] + + VarSetCapacity(vtblUnk, extfuncs.Length() * A_PtrSize) + + for i, name in extfuncs + NumPut(RegisterCallback("IUnknown_" . name), vtblUnk, (i-1) * A_PtrSize) + } + if (!VarSetCapacity(vtblRms)) { + extfuncs := ["GetServiceType", "GetApplicationName", "GetScriptableObject", "GetCustomUIMode"] + + VarSetCapacity(vtblRms, (3 + extfuncs.Length()) * A_PtrSize) + DllCall("ntdll\RtlMoveMemory", "Ptr", &vtblRms, "Ptr", &vtblUnk, "Ptr", A_PtrSize * 3) + + for i, name in extfuncs + NumPut(RegisterCallback("IWMPRemoteMediaServices_" . name, "Fast"), vtblRms, (2+i) * A_PtrSize) + } + if (!VarSetCapacity(vtblIsp)) { + VarSetCapacity(vtblIsp, 4 * A_PtrSize) + DllCall("ntdll\RtlMoveMemory", "Ptr", &vtblIsp, "Ptr", &vtblUnk, "Ptr", A_PtrSize * 3) + NumPut(RegisterCallback("IServiceProvider_QueryService", "Fast"), vtblIsp, A_PtrSize * 3) + } + if (!VarSetCapacity(vtblOls)) { + extfuncs := ["SaveObject", "GetMoniker", "GetContainer", "ShowObject", "OnShowWindow", "RequestNewObjectLayout"] + VarSetCapacity(vtblOls, (3 + extfuncs.Length()) * A_PtrSize) + DllCall("ntdll\RtlMoveMemory", "Ptr", &vtblOls, "Ptr", &vtblUnk, "Ptr", A_PtrSize * 3) + + for i, name in extfuncs + NumPut(RegisterCallback("IOleClientSite_" . name, "Fast"), vtblOls, (2+i) * A_PtrSize) + } + if (!vtblPtrs) + vtblPtrs := [&vtblUnk, &vtblRms, &vtblIsp, &vtblOls] + + pObj := DllCall("GlobalAlloc", "UInt", 0x0000, "Ptr", IWMPRemoteMediaServices_size, "Ptr") + for i, ptr in vtblPtrs { + off := (A_PtrSize * (i - 1)) + (4 * (i - 1)) + NumPut(ptr, pObj+0, off, "Ptr") + NumPut(off, pObj+0, off + A_PtrSize, "UInt") + } + NumPut(1, pObj+0, IWMPRemoteMediaServices_size - 4, "UInt") + + return pObj +} + +IUnknown_QueryInterface(this_, riid, ppvObject) +{ + static IID_IUnknown, IID_IWMPRemoteMediaServices, IID_IServiceProvider, IID_IOleClientSite + if (!VarSetCapacity(IID_IUnknown)) + VarSetCapacity(IID_IUnknown, 16), VarSetCapacity(IID_IWMPRemoteMediaServices, 16), VarSetCapacity(IID_IServiceProvider, 16), VarSetCapacity(IID_IOleClientSite, 16) + ,DllCall("ole32\CLSIDFromString", "WStr", "{00000000-0000-0000-C000-000000000046}", "Ptr", &IID_IUnknown) + ,DllCall("ole32\CLSIDFromString", "WStr", "{CBB92747-741F-44FE-AB5B-F1A48F3B2A59}", "Ptr", &IID_IWMPRemoteMediaServices) + ,DllCall("ole32\CLSIDFromString", "WStr", "{6d5140c1-7436-11ce-8034-00aa006009fa}", "Ptr", &IID_IServiceProvider) + ,DllCall("ole32\CLSIDFromString", "WStr", "{00000118-0000-0000-C000-000000000046}", "Ptr", &IID_IOleClientSite) + + if (DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IUnknown)) { + off := NumGet(this_+0, A_PtrSize, "UInt") + NumPut(this_ - off, ppvObject+0, "Ptr") + IUnknown_AddRef(this_) + return 0 ; S_OK + } + + if (DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IWMPRemoteMediaServices)) { + off := NumGet(this_+0, A_PtrSize, "UInt") + NumPut((this_ - off)+(A_PtrSize + 4), ppvObject+0, "Ptr") + IUnknown_AddRef(this_) + return 0 ; S_OK + } + + if (DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IServiceProvider)) { + off := NumGet(this_+0, A_PtrSize, "UInt") + NumPut((this_ - off)+((A_PtrSize + 4) * 2), ppvObject+0, "Ptr") + IUnknown_AddRef(this_) + return 0 ; S_OK + } + + if (DllCall("ole32\IsEqualGUID", "Ptr", riid, "Ptr", &IID_IOleClientSite)) { + off := NumGet(this_+0, A_PtrSize, "UInt") + NumPut((this_ - off)+((A_PtrSize + 4) * 3), ppvObject+0, "Ptr") + IUnknown_AddRef(this_) + return 0 ; S_OK + } + + NumPut(0, ppvObject+0, "Ptr") + return 0x80004002 ; E_NOINTERFACE +} + +IUnknown_AddRef(this_) +{ + global IWMPRemoteMediaServices_size + off := NumGet(this_+0, A_PtrSize, "UInt") + iunk := this_-off + NumPut((_refCount := NumGet(iunk+0, IWMPRemoteMediaServices_size - 4, "UInt") + 1), iunk+0, IWMPRemoteMediaServices_size - 4, "UInt") + return _refCount +} + +IUnknown_Release(this_) { + global IWMPRemoteMediaServices_size + off := NumGet(this_+0, A_PtrSize, "UInt") + iunk := this_-off + _refCount := NumGet(iunk+0, IWMPRemoteMediaServices_size - 4, "UInt") + if (_refCount > 0) { + NumPut(--_refCount, iunk+0, IWMPRemoteMediaServices_size - 4, "UInt") + if (_refCount == 0) + DllCall("GlobalFree", "Ptr", iunk, "Ptr") + } + return _refCount +} + +IWMPRemoteMediaServices_GetServiceType(this_, pbstrType) +{ + NumPut(DllCall("oleaut32\SysAllocString", "WStr", "Remote", "Ptr"), pbstrType+0, "Ptr") + return 0 +} + +IWMPRemoteMediaServices_GetApplicationName(this_, pbstrName) +{ + NumPut(DllCall("oleaut32\SysAllocString", "WStr", "qwerty12's long-ass AHK script for something that should've been simple: the case for using foobar2000", "Ptr"), pbstrName+0, "Ptr") + return 0 +} + +IWMPRemoteMediaServices_GetScriptableObject(this_, pbstrName, ppDispatch) +{ + return 0x80004001 +} +IWMPRemoteMediaServices_GetCustomUIMode(this_, pbstrFile) +{ + return 0x80004001 +} + +IServiceProvider_QueryService(this_, guidService, riid, ppvObject) +{ + return IUnknown_QueryInterface(this_, riid, ppvObject) +} + +IOleClientSite_SaveObject(this_) +{ + return 0x80004001 +} + +IOleClientSite_GetMoniker(this_, dwAssign, dwWhichMoniker, ppmk) +{ + return 0x80004001 +} + +IOleClientSite_GetContainer(this_, ppContainer) +{ + NumGet(0, ppContainer+0, "Ptr") + return 0x80004002 +} + +IOleClientSite_ShowObject(this_) +{ + return 0x80004001 +} + +IOleClientSite_OnShowWindow(this_, fShow) +{ + return 0x80004001 +} + +IOleClientSite_RequestNewObjectLayout(this_) +{ + return 0x80004001 +} \ No newline at end of file diff --git a/GetWindowsMediaPlayerPlayState/README.txt b/GetWindowsMediaPlayerPlayState/README.txt new file mode 100644 index 0000000..75501b7 --- /dev/null +++ b/GetWindowsMediaPlayerPlayState/README.txt @@ -0,0 +1,7 @@ +This script tells you the current playing state of a running Windows Media Player instance. I put this script here because of how complex WMP makes it to tell you its state. I hope this might help somebody. + +Resources used: + * The "remoteHost" example of https://github.com/Microsoft/Windows-classic-samples + * manuell's post here: https://stackoverflow.com/a/19571308 + +Tested with Windows 10 1703 / WMP 12 / AutoHotkey x64 1.1.26.01 \ No newline at end of file diff --git a/GhostedMenuIconForHiddenFiles/GhostedMenuIconForHiddenFiles.ahk b/GhostedMenuIconForHiddenFiles/GhostedMenuIconForHiddenFiles.ahk new file mode 100644 index 0000000..078de83 --- /dev/null +++ b/GhostedMenuIconForHiddenFiles/GhostedMenuIconForHiddenFiles.ahk @@ -0,0 +1,78 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +; #Warn ; Enable warnings to assist with detecting common errors. +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. + +; Show a menu of the first n files matching a pattern, and their icons. +pattern = %A_ScriptDir%\* +n = 15 + +VarSetCapacity(ICONINFO, (cbICONINFO := 32)), VarSetCapacity(BITMAP, 32) +; Allocate memory for a SHFILEINFOW struct. +VarSetCapacity(fileinfo, fisize := A_PtrSize + 688) + +Loop, Files, %pattern%, FD +{ + ; Add a menu item for each file. + Menu F, Add, %A_LoopFileName%, donothing + + ; Get the file's icon. + if DllCall("shell32\SHGetFileInfoW", "wstr", A_LoopFileFullPath + , "uint", 0, "ptr", &fileinfo, "uint", fisize, "uint", 0x100 | SHGFI_ATTRIBUTES := 0x000000800) + { + hicon := NumGet(fileinfo, 0, "ptr") + dwAttributes := NumGet(fileinfo, A_PtrSize + 4, "UInt") + if (dwAttributes & SFGAO_GHOSTED := 0x00008000) { + if (DllCall("GetIconInfo", "Ptr", hicon, "Ptr", &ICONINFO)) { + hbmColor := NumGet(ICONINFO, cbICONINFO - A_PtrSize, "Ptr") + hbmMask := NumGet(ICONINFO, cbICONINFO - (A_PtrSize * 2), "Ptr") + + if (DllCall("GetObject", "Ptr", hbmColor, "Int", A_PtrSize == 8 ? 32 : 24, "Ptr", &BITMAP)) { + width := NumGet(BITMAP, 4, "Int") + height := NumGet(BITMAP, 8, "Int") + + if ((im := IL_Create(1, 0, True))) { + if ((idx := DllCall("ImageList_Add", "Ptr", im, "Ptr", hbmColor, "Ptr", hbmMask)) != -1) { + rgbBk := DllCall("GetSysColor", "UInt", COLOR_MENU := 4, "UInt") + rgbFg := RGB(255, 255, 255) + scrdc := DllCall("GetDC", "Ptr", A_ScriptHwnd, "Ptr") + hdc := DllCall("CreateCompatibleDC", "Ptr", scrdc, "Ptr") + + DllCall("SelectObject", "Ptr", hdc, "Ptr", hbmMask, "Ptr") + if (DllCall("ImageList_DrawEx", "Ptr", im, "Int", idx, "Ptr", hdc, "Int", 2, "Int", 0, "Int", width, "Int", height, "UInt", rgbBk, "UInt", rgbFg, "UInt", ILD_MASK := 0x00000010 | ILD_BLEND50 := 0x00000004)) { + DllCall("SelectObject", "Ptr", hdc, "Ptr", hbmColor, "Ptr") + DllCall("ImageList_DrawEx", "Ptr", im, "Int", idx, "Ptr", hdc, "Int", 0, "Int", 0, "Int", width, "Int", height, "UInt", rgbBk, "UInt", rgbFg, "UInt", ILD_BLEND50 := 0x00000004) + DllCall("SelectObject", "Ptr", hdc, "Ptr", 0, "Ptr") + + DllCall("DestroyIcon", "Ptr", hicon) + hicon := DllCall("CreateIconIndirect", "Ptr", &ICONINFO, "Ptr") + } + DllCall("DeleteDC", "Ptr", hdc) + DllCall("ReleaseDC", "Ptr", 0, "Ptr", scrdc) + } + IL_Destroy(im) + } + } + + if (hbmColor) + DllCall("DeleteObject", "Ptr", hbmColor) + + if (hbmMask) + DllCall("DeleteObject", "Ptr", hbmMask) + } + } + ; Set the menu item's icon. + Menu F, Icon, %A_Index%&, HICON:%hicon% + ; Because we used ":" and not ":*", the icon will be automatically + ; freed when the program exits or if the menu or item is deleted. + } +} +until A_Index = n +Menu F, Show +donothing: +return + +RGB(r,g,b) +{ + return (r)|(g << 8)|(b << 16) +} \ No newline at end of file diff --git a/GhostedMenuIconForHiddenFiles/README.md b/GhostedMenuIconForHiddenFiles/README.md new file mode 100644 index 0000000..a5878a8 --- /dev/null +++ b/GhostedMenuIconForHiddenFiles/README.md @@ -0,0 +1,3 @@ +NOTE: You should use iPhilip's script [here](https://autohotkey.com/boards/viewtopic.php?f=5&t=41587#p189771) which does the same thing with far less code. + +This script uses the code from https://autohotkey.com/docs/misc/ImageHandles.htm to show a list of files that are in the same folder it's running from, with the addition of applying a similar effect to hidden files' icons as Explorer does. \ No newline at end of file diff --git a/GoodbyeDPITray/GoodbyeDPITray.ahk b/GoodbyeDPITray/GoodbyeDPITray.ahk new file mode 100644 index 0000000..15eec62 --- /dev/null +++ b/GoodbyeDPITray/GoodbyeDPITray.ahk @@ -0,0 +1,583 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +SetBatchLines, -1 +ListLines, Off +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. +#KeyHistory 0 +#NoTrayIcon +#SingleInstance Force + +main(), return + +main() +{ + global exe := A_ScriptDir . "\goodbyedpi.exe", arguments := "-e 8 -s" + , gdpiOutput, processHandleSwitch := " /procToTerminateHandle:", processWaitTimeout := 2000 + , startTorStr := "Start &Tor", stopTorStr := "Stop &Tor" + + cmdLine := DllCall("GetCommandLineW", "WStr") + if (InStr(cmdLine, processHandleSwitch)) { + ; I can't stop child processes from fucking inheriting the IGNORE_CTRL_C flag from the PEB, so have said flag set in a child process which is then summarily ended + if ((hProcess := StrSplit(cmdLine, processHandleSwitch, " """"")[2])) { + if ((gdpiPid := DllCall("GetProcessId", "Ptr", hProcess, "UInt"))) + _StopGoodbyeDPI(hProcess, gdpiPid) + DllCall("CloseHandle", "Ptr", hProcess) + } + + ExitApp + } + + if not (A_IsAdmin or RegExMatch(cmdLine, " /restart(?!\S)")) + { + try + { + if !A_IsCompiled + Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%" + else + Run *RunAs "%A_ScriptFullPath%" /restart + } + ExitApp + } + + if (!VarSetCapacity(gdpiOutput)) + VarSetCapacity(gdpiOutput, 8192) + + Menu, Tray, NoStandard + Menu, Tray, Add, &Start/Stop GoodbyeDPI, ToggleGoodbyeDPI + Menu, Tray, Add, View GoodbyeDPI output, ShowGoodbyeDPIOutput + Menu, Tray, Add + Menu, Tray, Add, %startTorStr%, Tor + Menu, Tray, Add + Menu, Tray, Add, Edit This Script, Edit + Menu, Tray, Add, E&xit, ExitApp + Menu, Tray, Default, 2& + OnMessage(0x404, "AHK_NOTIFYICON") + + setTrayState(False) + ,OnExit("AtExit") + Menu, Tray, Icon +} + +AtExit(ExitReason, ExitCode) +{ + global ctx, processWaitTimeout, stopTorStr + OnExit(A_ThisFunc, 0) + Tor(stopTorStr) + if (IsObject(ctx)) + if (DllCall("WaitForSingleObject", "Ptr", NumGet(ctx["pi"]+0,0,"Ptr"), "UInt", 0) == 258) { + processWaitTimeout := 500 + ,ToggleGoodbyeDPI(True, False) + } + AHK_TERMNOTIFY(0) + if (ExitReason == "Shutdown") + UnloadWinDivert() + return 0 +} + +ToggleGoodbyeDPI(useWTFMS := True, useTerminateSubprocess := True) +{ + static cbStartupInfoEx := A_PtrSize == 8 ? 112 : 72 + global exe, arguments, ctx, twGlobal := 0, gdpiOutput, processHandleSwitch, processWaitTimeout + + if (IsObject(ctx)) { + hProcess := NumGet(ctx["pi"]+0,0,"Ptr") + if (useTerminateSubprocess) { + useTerminateSubprocess := False + ,DllCall("InitializeProcThreadAttributeList", "Ptr", 0, "UInt", 1, "UInt", 0, "Ptr*", size) + if (size) { + VarSetCapacity(AttributeList, size + A_PtrSize) + + if (DllCall("InitializeProcThreadAttributeList", "Ptr", &AttributeList, "UInt", 1, "UInt", 0, "Ptr*", size)) { + NumPut(hProcess, AttributeList, size, "Ptr") + if (DllCall("UpdateProcThreadAttribute", "Ptr", &AttributeList, "UInt", 0, "UPtr", 0x00020002, "Ptr", &AttributeList+size, "Ptr", A_PtrSize, "Ptr", 0, "Ptr", 0)) { + if (DllCall("SetHandleInformation", "Ptr", hProcess, "UInt", 0x00000001, "UInt", 0x00000001)) { + VarSetCapacity(pi, 24, 0) + ,VarSetCapacity(info, cbStartupInfoEx, 0) + ,NumPut(cbStartupInfoEx, info,, "UInt") + ,NumPut(&AttributeList, info, cbStartupInfoEx - A_PtrSize, "Ptr") + + if (DllCall("CreateProcess", "Str", A_AhkPath, "Str", """" . A_AhkPath . """" . " /force """ . A_ScriptFullPath . """" . processHandleSwitch . hProcess, "Ptr", 0, "Ptr", 0, "Int", True, "UInt", 0x00080000, "Ptr", 0, "Ptr", 0, "Ptr", &info, "Ptr", &pi)) { + Menu, Tray, Disable, 1& + hSubProcess := NumGet(pi,, "Ptr") + ,DllCall("CloseHandle", "Ptr", NumGet(pi, A_PtrSize, "Ptr")) + ,MsgSleep(hSubProcess, processWaitTimeout) + ,DllCall("CloseHandle", "Ptr", hSubProcess) + ,useTerminateSubprocess := True + } + } + } + DllCall("DeleteProcThreadAttributeList", "Ptr", &AttributeList) + } + } + } + if (!useTerminateSubprocess) + _StopGoodbyeDPI(hProcess, NumGet(ctx["pi"]+0, 2 * A_PtrSize, "UInt")) + } else { + Menu, Tray, Disable, 1& + gdpiOutput := "" + ,ctx := StdoutToVar_CreateProcess("""" . exe . """" . (arguments ? A_Space . arguments : ""),, A_ScriptDir . "\NoStdoutBuffering.dll") + + if (IsObject(ctx)) { + twGlobal := TermWait_WaitForProcTerm(A_ScriptHwnd, NumGet(ctx["pi"]+0,0,"Ptr")) + ,setTrayState(True) + ,GetGoodbyeDPIOutput() + } else { + MsgBox Process creation failed + Menu, Tray, Enable, 1& + return + } + } + if (useWTFMS) + WTFMS() + else + WinActivate % "ahk_id " . GetTaskbarVisibleWindows(1)[1] +} + +; From kon +AHK_NOTIFYICON(wParam, lParam) +{ + global stopTorStr, startTorStr + if (lParam == 0x205) { + try Menu, Tray, Rename, 4&, % Tor("") ? stopTorStr : startTorStr + } else if (lParam == 0x0207) { + ToggleGoodbyeDPI(False) + } +} + +Tor(mode) +{ + global stopTorStr, startTorStr + static SERVICE_STATUS, SERVICE_NO_CHANGE := 0xffffffff + if (!VarSetCapacity(SERVICE_STATUS)) + VarSetCapacity(SERVICE_STATUS, 28) + + if (mode == stopTorStr) + stopTor := True + else if (mode == startTorStr) + startTor := True + else + getStatus := True + + if ((HSC := DllCall("Advapi32.dll\OpenSCManager", "Ptr", 0, "Ptr", 0, "UInt", 0x000F0000 | 0x0001, "UPtr"))) { + Loop { + if ((HSV := DllCall("Advapi32.dll\OpenService", "Ptr", HSC, "Str", "tor", "UInt", 0x000F0000 | 0x0002 | 0x0004 | 0x0010 | 0x0020, "UPtr"))) { + if (getStatus) { + if (DllCall("Advapi32.dll\QueryServiceStatus", "Ptr", HSV, "Ptr", &SERVICE_STATUS)) + dwCurrentState := NumGet(SERVICE_STATUS, 4, "UInt") + } else { + ; toggle: if (dwCurrentState == 0x00000004) + if (stopTor) { + DllCall("Advapi32.dll\ChangeServiceConfig", "Ptr", HSV, "UInt", SERVICE_NO_CHANGE, "UInt", 4, "UInt", SERVICE_NO_CHANGE, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0) + DllCall("Advapi32.dll\ControlService", "Ptr", HSV, "UInt", 0x00000001, "Ptr", &SERVICE_STATUS) + } + else if (startTor) { + if (A_Index == 1) { + DllCall("Advapi32.dll\ChangeServiceConfig", "Ptr", HSV, "UInt", SERVICE_NO_CHANGE, "UInt", 3, "UInt", SERVICE_NO_CHANGE, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0) + } else { + DllCall("Advapi32.dll\StartService", "Ptr", HSV, "UInt", 0, "Ptr", 0) + DllCall("Advapi32.dll\ChangeServiceConfig", "Ptr", HSV, "UInt", SERVICE_NO_CHANGE, "UInt", 4, "UInt", SERVICE_NO_CHANGE, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0) + } + } + } + DllCall("Advapi32.dll\CloseServiceHandle", "Ptr", HSV) + } + if (!startTor || A_Index != 1) + break + } + DllCall("Advapi32.dll\CloseServiceHandle", "Ptr", HSC) + } + + return dwCurrentState == 0x00000004 +} + +_StopGoodbyeDPI(hProcess, gdpiPid) +{ + global processWaitTimeout + + shouldKill := True + if (DllCall("AttachConsole", "UInt", gdpiPid)) { + DllCall("SetConsoleCtrlHandler", "Ptr", 0, "Int", True) + ,generated := DllCall("GenerateConsoleCtrlEvent", "UInt", 0, "UInt", 0) + ,DllCall("FreeConsole") + if (generated) + shouldKill := DllCall("WaitForSingleObject", "Ptr", hProcess, "UInt", processWaitTimeout, "UInt") != 0 + } + if (shouldKill) { + if ((ExitProcess := ProcAddressFromRemoteProcess(hProcess, "kernel32.dll", "ExitProcess"))) { + if ((hRemoteThread := DllCall("CreateRemoteThread", "Ptr", hProcess, "Ptr", 0, "Ptr", 0, "Ptr", ExitProcess, "Ptr", 1, "UInt", 0, "Ptr", 0, "Ptr"))) { + DllCall("CloseHandle", "Ptr", hRemoteThread) + shouldKill := DllCall("WaitForSingleObject", "Ptr", hProcess, "UInt", processWaitTimeout, "UInt") != 0 + } + } + } + if (shouldKill) + DllCall("TerminateProcess", "Ptr", hProcess, "UInt", 0) +} + +setTrayState(on) +{ + global exe, gdpiOutput + static offIcon := A_ScriptDir . "\off.ico" + try { + Menu, Tray, Enable, 1& + if (!on) { + Menu, Tray, Icon, %offIcon% + Menu, Tray, Tip, GoodbyeDPI stopped + if (gdpiOutput) + Menu, Tray, Rename, 2&, &View last GoodbyeDPI output + else + Menu, Tray, Disable, 2& + Menu, Tray, Rename, 1&, &Start GoodbyeDPI + } else { + Menu, Tray, Icon, %exe% + Menu, Tray, Tip, GoodbyeDPI started + Menu, Tray, Rename, 1&, &Stop GoodbyeDPI + Menu, Tray, Rename, 2&, &View GoodbyeDPI output + Menu, Tray, Enable, 2& + } + } +} + +AHK_TERMNOTIFY(pGlobal) +{ + global ctx, twGlobal + if (!pGlobal) + pGlobal := twGlobal + TermWait_StopWaiting(pGlobal) + ,StdoutToVar_Cleanup(ctx) + ,twGlobal := 0, ctx := "" + ,setTrayState(False) +} + +GetGoodbyeDPIOutput() +{ + global ctx, gdpiOutput + + if (!DllCall("PeekNamedPipe", "Ptr", ctx.hStdOutRd, "Ptr", 0, "UInt", 0, "Ptr", 0, "UIntP", nTot, "Ptr", 0) || !nTot) + return + + VarSetCapacity(sTemp, nTot+2) + ,DllCall( "ReadFile", Ptr,ctx.hStdOutRd, Ptr,&sTemp, UInt,nTot, PtrP,nSize, Ptr,0 ) + ,gdpiOutput .= StrGet(&sTemp, nSize, "CP0") +} + +ShowGoodbyeDPIOutput() +{ + global gdpiOutput + + GetGoodbyeDPIOutput() + + if (gdpiOutput) + MsgBox %gdpiOutput% +} + +; --- + +StdoutToVar_CreateProcess(sCmd, sDir:="", dllPath:="") { + ; https://autohotkey.com/boards/viewtopic.php?t=791 + ; Author .......: Sean (http://goo.gl/o3VCO8), modified by nfl and by Cyruz. Modified by qwerty12 to add quick and dirty DLL injection, and to abstract the pipe reading logic into its own function + ; License ......: WTFPL - http://www.wtfpl.net/txt/copying/ + + DllCall( "CreatePipe", PtrP,hStdOutRd, PtrP,hStdOutWr, Ptr,0, UInt,0 ) + DllCall( "SetHandleInformation", Ptr,hStdOutWr, UInt,1, UInt,1 ) + + pi := DllCall("GlobalAlloc", "UInt", 0x0040, "Ptr", (A_PtrSize == 4) ? 16 : 24, "Ptr") + si := DllCall("GlobalAlloc", "UInt", 0x0040, "Ptr", (siSz := (A_PtrSize == 4) ? 68 : 104), "Ptr") + NumPut( siSz, si+0, 0, "UInt" ) + NumPut( 0x100, si+0, (A_PtrSize == 4) ? 44 : 60, "UInt" ) + NumPut( hStdOutWr, si+0, (A_PtrSize == 4) ? 60 : 88, "Ptr" ) + NumPut( hStdOutWr, si+0, (A_PtrSize == 4) ? 64 : 96, "Ptr" ) + + If ( !DllCall( "CreateProcess", Ptr,0, Ptr,&sCmd, Ptr,0, Ptr,0, Int,True, UInt,(CREATE_NO_WINDOW := 0x08000000 | CREATE_SUSPENDED := 0x00000004) + , Ptr,0, Ptr,sDir?&sDir:0, Ptr,si, Ptr,pi ) ) + Return 0 + , DllCall( "CloseHandle", Ptr,hStdOutWr ) + , DllCall( "CloseHandle", Ptr,hStdOutRd ) + , DllCall("GlobalFree", "Ptr", si, "Ptr") + , DllCall("GlobalFree", "Ptr", pi, "Ptr") + + DllCall( "CloseHandle", Ptr,hStdOutWr ) ; The write pipe must be closed before reading the stdout. + + ret := {"pi": pi, "si": si, "hStdOutRd": hStdOutRd} + + ok := True + if (FileExist(dllPath)) { + static GetBinaryType := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "kernel32.dll", "Ptr"), "AStr", A_IsUnicode ? "GetBinaryTypeW" : "GetBinaryTypeA", "Ptr") + ,LoadLibrary := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "kernel32.dll", "Ptr"), "AStr", A_IsUnicode ? "LoadLibraryW" : "LoadLibraryA", "Ptr") + ok := False + cbDllPath := VarSetCapacity(dllPath) + + if ((DllCall(GetBinaryType, "Str", StrSplit(sCmd, """", """")[2], "UInt*", BinaryType))) { + if ((BinaryType == 6 && A_PtrSize == 8) || (BinaryType == 0 && A_PtrSize == 4)) { + if ((pRemoteDllPath := DllCall("VirtualAllocEx", "Ptr", (hProcess := NumGet(pi+0,0,"Ptr")), "Ptr", 0, "Ptr", cbDllPath, "UInt", MEM_COMMIT := 0x00001000, "UInt", PAGE_READWRITE := 0x04, "Ptr"))) { + if (DllCall("WriteProcessMemory", "Ptr", hProcess, "Ptr", pRemoteDllPath, "Ptr", &dllPath, "Ptr", cbDllPath, "Ptr", 0)) { + if (hRemoteThread := DllCall("CreateRemoteThread", "Ptr", hProcess, "Ptr", 0, "Ptr", 0, "Ptr", LoadLibrary, "Ptr", pRemoteDllPath, "UInt", 0, "Ptr", 0, "Ptr")) { + DllCall("WaitForSingleObject", "Ptr", hRemoteThread, "UInt", 0xFFFFFFFF) ; don't use MsgWaitForMultipleObjectsEx here and let this block. There's gonna be problems anyway if this fails - having the AutoHotkey script blocked is no problem + DllCall("CloseHandle", "Ptr", hRemoteThread) + ok := True + } + } + DllCall("VirtualFreeEx", "Ptr", hProcess, "Ptr", pRemoteDllPath, "Ptr", 0, "UInt", MEM_RELEASE := 0x8000) + } + } + } + } + + if (ok) + DllCall("ResumeThread", "Ptr", NumGet(pi+0,A_PtrSize)) + else { + DllCall("TerminateProcess", "Ptr", hProcess, "UInt", 1) + StdoutToVar_Cleanup(ret) + ret := 0 + } + + Return ret +} + +StdoutToVar_Cleanup(stvCtx) +{ + if (IsObject(stvCtx)) { + DllCall( "CloseHandle", Ptr,NumGet(stvCtx["pi"]+0,0) ) + DllCall( "CloseHandle", Ptr,NumGet(stvCtx["pi"]+0,A_PtrSize) ) + DllCall( "CloseHandle", Ptr,stvCtx.hStdOutRd ) + + DllCall("GlobalFree", "Ptr", stvCtx["si"], "Ptr") + DllCall("GlobalFree", "Ptr", stvCtx["pi"], "Ptr") + } +} + +TermWait_WaitForProcTerm(hWnd, hProcess, ByRef sDataIn:="") { + ; Author .......: Cyruz (http://ciroprincipe.info) & SKAN (http://goo.gl/EpCq0Z) + ; License ......: WTFPL - http://www.wtfpl.net/txt/copying/ + static addrCallback := RegisterSyncCallback("AHK_TERMNOTIFY") + + if (hProcess < 1) + return 0 + + szDataIn := VarSetCapacity(sDataIn) + pGlobal := DllCall("GlobalAlloc", "UInt", 0x0040, "UInt", (A_PtrSize == 8 ? 32 : 20) + szDataIn, "Ptr") + + NumPut(hWnd, pGlobal+0,, "Ptr") + NumPut(hProcess, pGlobal+0, A_PtrSize == 8 ? 16 : 12, "Ptr") + + DllCall("RtlMoveMemory", "Ptr", pGlobal+(A_PtrSize == 8 ? 32 : 20), "Ptr", &sDataIn, "Ptr", szDataIn) + if (!DllCall("RegisterWaitForSingleObject", "Ptr", pGlobal+(A_PtrSize == 8 ? 24 : 16), "Ptr", hProcess, "Ptr", addrCallback + , "Ptr", pGlobal, "UInt", 0xFFFFFFFF, "UInt", 0x00000004 | 0x00000008)) { ; INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE + DllCall("GlobalFree", "Ptr", pGlobal, "Ptr") + return 0 + } + return pGlobal +} + +TermWait_StopWaiting(pGlobal) { + if (pGlobal) { + DllCall("UnregisterWait", "Ptr", NumGet(pGlobal+0, A_PtrSize == 8 ? 24 : 16, "Ptr")) + DllCall("GlobalFree", "Ptr", pGlobal, "Ptr") + } +} + +RegisterSyncCallback(FunctionName, Options:="", ParamCount:="") +{ + ; Author: lexikos (https://autohotkey.com/boards/viewtopic.php?t=21223) + if !(fn := Func(FunctionName)) || fn.IsBuiltIn + throw Exception("Bad function", -1, FunctionName) + if (ParamCount == "") + ParamCount := fn.MinParams + if (ParamCount > fn.MaxParams && !fn.IsVariadic || ParamCount+0 < fn.MinParams) + throw Exception("Bad param count", -1, ParamCount) + + static sHwnd := 0, sMsg, sSendMessageW + if !sHwnd + { + Gui RegisterSyncCallback: +Parent%A_ScriptHwnd% +hwndsHwnd + OnMessage(sMsg := 0x8000, Func("RegisterSyncCallback_Msg")) + sSendMessageW := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "user32.dll", "ptr"), "astr", "SendMessageW", "ptr") + } + + if !(pcb := DllCall("GlobalAlloc", "uint", 0, "ptr", 96, "ptr")) + throw + DllCall("VirtualProtect", "ptr", pcb, "ptr", 96, "uint", 0x40, "uint*", 0) + + p := pcb + if (A_PtrSize = 8) + { + /* + 48 89 4c 24 08 ; mov [rsp+8], rcx + 48 89 54'24 10 ; mov [rsp+16], rdx + 4c 89 44 24 18 ; mov [rsp+24], r8 + 4c'89 4c 24 20 ; mov [rsp+32], r9 + 48 83 ec 28' ; sub rsp, 40 + 4c 8d 44 24 30 ; lea r8, [rsp+48] (arg 3, ¶ms) + 49 b9 .. ; mov r9, .. (arg 4, operand to follow) + */ + p := NumPut(0x54894808244c8948, p+0) + p := NumPut(0x4c182444894c1024, p+0) + p := NumPut(0x28ec834820244c89, p+0) + p := NumPut( 0xb9493024448d4c, p+0) - 1 + lParamPtr := p, p += 8 + + p := NumPut(0xba, p+0, "char") ; mov edx, nmsg + p := NumPut(sMsg, p+0, "int") + p := NumPut(0xb9, p+0, "char") ; mov ecx, hwnd + p := NumPut(sHwnd, p+0, "int") + p := NumPut(0xb848, p+0, "short") ; mov rax, SendMessageW + p := NumPut(sSendMessageW, p+0) + /* + ff d0 ; call rax + 48 83 c4 28 ; add rsp, 40 + c3 ; ret + */ + p := NumPut(0x00c328c48348d0ff, p+0) + } + else ;(A_PtrSize = 4) + { + p := NumPut(0x68, p+0, "char") ; push ... (lParam data) + lParamPtr := p, p += 4 + p := NumPut(0x0824448d, p+0, "int") ; lea eax, [esp+8] + p := NumPut(0x50, p+0, "char") ; push eax + p := NumPut(0x68, p+0, "char") ; push nmsg + p := NumPut(sMsg, p+0, "int") + p := NumPut(0x68, p+0, "char") ; push hwnd + p := NumPut(sHwnd, p+0, "int") + p := NumPut(0xb8, p+0, "char") ; mov eax, &SendMessageW + p := NumPut(sSendMessageW, p+0, "int") + p := NumPut(0xd0ff, p+0, "short") ; call eax + p := NumPut(0xc2, p+0, "char") ; ret argsize + p := NumPut((InStr(Options, "C") ? 0 : ParamCount*4), p+0, "short") + } + NumPut(p, lParamPtr+0) ; To be passed as lParam. + p := NumPut(&fn, p+0) + p := NumPut(ParamCount, p+0, "int") + return pcb +} + +RegisterSyncCallback_Msg(wParam, lParam) +{ + if (A_Gui != "RegisterSyncCallback") + return + fn := Object(NumGet(lParam + 0)) + paramCount := NumGet(lParam + A_PtrSize, "int") + params := [] + Loop % paramCount + params.Push(NumGet(wParam + A_PtrSize * (A_Index-1))) + return %fn%(params*) +} + +UnloadWinDivert() +{ + return + ; Note: doing the following prevents GoodbyeDPI from being loaded again. In the case of fast startup, the driver kernel state of this most probably persists, which is why I don't do this even on shutdown + if ((SCM := DllCall("Advapi32\OpenSCManager", "Ptr", 0, "Ptr", 0, "UInt", 0xF003F, "Ptr"))) { + if ((SVC := DllCall("Advapi32\OpenService", "Ptr", SCM, "Str", "WinDivert1.3", "UInt", 0x0001 | 0x0002 | 0x0004 | 0x0020, "Ptr"))) { + DllCall("Advapi32\DeleteService", "Ptr", SVC) + VarSetCapacity(SERVICE_STATUS, 28) + DllCall("Advapi32.dll\ControlService", "Ptr", SVC, "UInt", 0x00000001, "Ptr", &SERVICE_STATUS) + DllCall("Advapi32\CloseServiceHandle", "Ptr", SVC) + } + DllCall("Advapi32\CloseServiceHandle", "Ptr", SCM) + } + +} + +WTFMS() +{ + ; Author: robertcollier4: https://autohotkey.com/board/topic/91577-taskbarnavigation-switch-windows-in-taskbar-order-alt-tab-replacement/ + hwnd := DllCall("GetForegroundWindow", "Ptr") + loop { + hwnd := DllCall("GetWindow", "Ptr", hwnd, "Ptr", 2, "Ptr") + } until (DllCall("IsWindowVisible", "Ptr", hwnd)) + if (!DllCall("IsIconic", "Ptr", hwnd)) + if (!DllCall("SetForegroundWindow", "Ptr", hwnd)) + DllCall("SwitchToThisWindow", "Ptr", hwnd, "UInt", 1) +} + +MsgSleep(hObject, dwTimeout) +{ + static MsgWaitForMultipleObjectsEx := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandleW", "WStr", "user32.dll", "Ptr"), "AStr", "MsgWaitForMultipleObjectsEx", "Ptr") + ; Based on code by Raymond Chen, from https://blogs.msdn.microsoft.com/oldnewthing/20060126-00/?p=32513, and from Lexikos: https://autohotkey.com/board/topic/27515-fileextract-fileextract-tomem-counterpart-of-fileinstall/ + ; Assumes waiting will be done on one object, but adding support for more if needed is trivial + r := 0xFFFFFFFF, dwStart := A_TickCount + while ((dwElapsed := A_TickCount - dwStart) < dwTimeout) { + r := DllCall(MsgWaitForMultipleObjectsEx, "UInt", 1, "Ptr*", hObject, "UInt", dwTimeout - dwElapsed, "UInt", 0x4FF, "UInt", 0x6, "UInt") + if (r == 0 || r == 0xFFFFFFFF || r == 258) + break + Sleep -1 + } + return r +} + +; Very little error checking. TBH, I'd be surprised if someone actually uses this, so... +ProcAddressFromRemoteProcess(hProcess, sModuleName, targetFuncName, ByRef Magic := 0) +{ + if (!hProcess || !sModuleName || !targetFuncName) + return 0 + + MAX_PATH := 260 + INFINITE := 0xffffffff + LIST_MODULES_DEFAULT := 0x00 + Loop { + if (!DllCall("psapi\EnumProcessModulesEx", "Ptr", hProcess, "Ptr", 0, "UInt", 0, "UInt*", cbNeeded, "UInt", LIST_MODULES_DEFAULT)) + throw + VarSetCapacity(hModules, cbNeeded, 0) + } until (DllCall("psapi\EnumProcessModulesEx", "Ptr", hProcess, "Ptr", &hModules, "UInt", cbNeeded, "UInt*", cbNeeded, "UInt", LIST_MODULES_DEFAULT)) + + VarSetCapacity(modName, (MAX_PATH + 2) * 2) + Loop % cbNeeded / A_PtrSize { + if (DllCall("psapi\GetModuleBaseName", "Ptr", hProcess, "Ptr", NumGet(hModules, A_PtrSize * (A_Index - 1), "Ptr"), "Str", modName, "UInt", MAX_PATH)) { + if (modName = sModuleName) { + hModule := NumGet(hModules, A_PtrSize * (A_Index - 1), "Ptr") + break + } + } + } + + if (!hModule) + return 0 + + ; MarkHC: https://www.unknowncheats.me/forum/1457119-post3.html + IMAGE_DOS_SIGNATURE := 0x5A4D, IMAGE_NT_SIGNATURE := 0x4550 + if (DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule, "UShort*", header, "Ptr", 2, "Ptr*", br) && br == 2 && header == IMAGE_DOS_SIGNATURE) { + if (DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+60, "Int*", e_lfanew, "Ptr", 4, "Ptr*", br) && DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+e_lfanew, "UInt*", Signature, "Ptr", 4, "Ptr*", br)) { + if (Signature == IMAGE_NT_SIGNATURE) { + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+e_lfanew+24, "UShort*", Magic, "Ptr", 2, "Ptr*", br) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+e_lfanew+24+(Magic == (IMAGE_NT_OPTIONAL_HDR64_MAGIC := 0x20b) ? 112 : 96), "UInt*", exportTableRVA, "Ptr", 4, "Ptr*", br) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+exportTableRVA+20, "UInt*", NumberOfFunctions, "Ptr", 4, "Ptr*", br) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+exportTableRVA+24, "UInt*", NumberOfNames, "Ptr", 4, "Ptr*", br) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+exportTableRVA+28, "UInt*", AddressOfFunctions, "Ptr", 4, "Ptr*", br) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+exportTableRVA+32, "UInt*", AddressOfNames, "Ptr", 4, "Ptr*", br) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+exportTableRVA+36, "UInt*", AddressOfNameOrdinals, "Ptr", 4, "Ptr*", br) + + VarSetCapacity(functions, NumberOfFunctions * 4) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+AddressOfFunctions, "Ptr", &functions, "Ptr", NumberOfFunctions * 4, "Ptr*", br) + VarSetCapacity(exports, NumberOfNames * 4) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+AddressOfNames, "Ptr", &exports, "Ptr", NumberOfNames * 4, "Ptr*", br) + VarSetCapacity(ordinals, NumberOfNames * 2) + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+AddressOfNameOrdinals, "Ptr", &ordinals, "Ptr", NumberOfNames * 2, "Ptr*", br) + + Loop % NumberOfNames { + addr := NumGet(exports, 4 * (A_Index - 1), "UInt") + i := 0, funcName := "" + while (true) { + DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", hModule+addr+i, "Int*", letter, "Ptr", 1, "Ptr*", br) + if (!letter) + break + funcName .= Chr(letter) + i += 1 + } + if (funcName == targetFuncName) { + ordinal := NumGet(ordinals, 2 * (A_Index - 1), "UShort") + return NumGet(functions, 4 * ordinal, "UInt") + hModule + } + } + } + } + } + return 0 +} + +Edit() { + Edit +} + +ExitApp() { + ExitApp +} diff --git a/GoodbyeDPITray/NoStdoutBuffering.dll b/GoodbyeDPITray/NoStdoutBuffering.dll new file mode 100644 index 0000000..7a63bd3 Binary files /dev/null and b/GoodbyeDPITray/NoStdoutBuffering.dll differ diff --git a/GoodbyeDPITray/NoStdoutBuffering.zip b/GoodbyeDPITray/NoStdoutBuffering.zip new file mode 100644 index 0000000..c29d0e7 Binary files /dev/null and b/GoodbyeDPITray/NoStdoutBuffering.zip differ diff --git a/GoodbyeDPITray/README.md b/GoodbyeDPITray/README.md new file mode 100644 index 0000000..5c67af1 --- /dev/null +++ b/GoodbyeDPITray/README.md @@ -0,0 +1,11 @@ +Very basic tray script to start/stop ValdikSS's [GoodbyeDPI](https://github.com/ValdikSS/GoodbyeDPI). + +The script tries to stop GoodbyeDPI correctly by having Windows send Ctrl+C to the script. + +Extract GoodbyeDPI's exe and WinDivert DLL and driver into the same folder. Edit the script to change the arguments it starts GoodbyeDPI with. + +If Tor is installed as a service, it can start/stop it too. + +To get around the problem explained on https://www.codeproject.com/Articles/16163/Real-Time-Console-Output-Redirection so that this script can view its output without hanging, GoodbyeDPI injects a DLL called NoStdoutBuffering.dll into GoodbyeDPI's process. NoStdoutBuffering (the source is included in the 7z file) is a very simple DLL that uses the excellent [MinHook](https://github.com/TsudaKageyu/minhook) library to hook isatty to stop the CRT logic of not flushing when stdout is a pipe. + +The included compiled NoStdoutBuffering.dll is for 64-bit only. If you're using a 64-bit Windows OS, it's recommended you only run this script with a 64-bit AutoHotkey. \ No newline at end of file diff --git a/GoodbyeDPITray/off.ico b/GoodbyeDPITray/off.ico new file mode 100644 index 0000000..e2ac79e Binary files /dev/null and b/GoodbyeDPITray/off.ico differ diff --git a/IFilterPDF/README.txt b/IFilterPDF/README.txt new file mode 100644 index 0000000..df68b33 --- /dev/null +++ b/IFilterPDF/README.txt @@ -0,0 +1,5 @@ +This is an example of a script that uses Microsoft's IFilter technology to look at files' contents. + +Since Windows 8 (because of Reader, I presume), Microsoft has included an IFilter support plugin for PDF files, allowing indexing of their contents out of the box. If you're on 7, just install SumatraPDF. + +You can also use this script to get the text contents of a Word document, provided the architecture of the installed Office matches the architecture of the AutoHotkey executable. \ No newline at end of file diff --git a/IFilterPDF/ifilter.ahk b/IFilterPDF/ifilter.ahk new file mode 100644 index 0000000..cff09fc --- /dev/null +++ b/IFilterPDF/ifilter.ahk @@ -0,0 +1,102 @@ +; IFilter AutoHotkey example by qwerty12 +; Credits: +; https://tlzprgmr.wordpress.com/2008/02/02/using-the-ifilter-interface-to-extract-text-from-documents/ +; https://stackoverflow.com/questions/7177953/loadifilter-fails-on-all-pdfs-but-mss-filtdump-exe-doesnt +; https://forums.adobe.com/thread/1086426?start=0&tstart=0 + +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +AutoTrim, Off +ListLines, Off +SetBatchLines, -1 +#KeyHistory 0 +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. + +; --- +#MaxMem 4 ; Might need to be multipled by 2 and 1 added to it because sizeof(WCHAR == 2). Not sure. It works for me as it is currently. +cchBufferSize := 4 * 1024 +; --- +resultstriplinebreaks := true +file := "" +searchstring := "" +; --- + +CHUNK_TEXT := 1 + +STGM_READ := 0 + +IFILTER_INIT_CANON_PARAGRAPHS := 1, +IFILTER_INIT_HARD_LINE_BREAKS := 2, +IFILTER_INIT_CANON_HYPHENS := 4, +IFILTER_INIT_CANON_SPACES := 8, +IFILTER_INIT_APPLY_INDEX_ATTRIBUTES := 16, +IFILTER_INIT_APPLY_OTHER_ATTRIBUTES := 32, +IFILTER_INIT_APPLY_CRAWL_ATTRIBUTES := 256, +IFILTER_INIT_INDEXING_ONLY := 64, +IFILTER_INIT_SEARCH_LINKS := 128, +IFILTER_INIT_FILTER_OWNED_VALUE_OK := 512, +IFILTER_INIT_FILTER_AGGRESSIVE_BREAK := 1024, +IFILTER_INIT_DISABLE_EMBEDDED := 2048, +IFILTER_INIT_EMIT_FORMATTING := 4096 + +S_OK := 0 +FILTER_S_LAST_TEXT := 268041 +FILTER_E_NO_MORE_TEXT := -2147215615 + +if (!A_IsUnicode) { + MsgBox The IFilter APIs appear to be Unicode only. Please try again with a Unicode build of AHK. + ExitApp +} + +if (!file || !searchstring) { + MsgBox Please make sure the file to search in and the string to search for is specified in %A_ScriptFullPath% + ExitApp +} + +SplitPath, file,,, ext +VarSetCapacity(FILTERED_DATA_SOURCES, 4*A_PtrSize, 0), NumPut(&ext, FILTERED_DATA_SOURCES,, "Ptr") +VarSetCapacity(FilterClsid, 16, 0) + +; Adobe workaround +if (job := DllCall("CreateJobObject", "Ptr", 0, "Str", "filterProc", "Ptr")) + DllCall("AssignProcessToJobObject", "Ptr", job, "Ptr", DllCall("GetCurrentProcess", "Ptr")) + +FilterRegistration := ComObjCreate("{9E175B8D-F52A-11D8-B9A5-505054503030}", "{c7310722-ac80-11d1-8df3-00c04fb6ef4f}") +if (DllCall(NumGet(NumGet(FilterRegistration+0)+3*A_PtrSize), "Ptr", FilterRegistration, "Ptr", 0, "Ptr", &FILTERED_DATA_SOURCES, "Ptr", 0, "Int", false, "Ptr", &FilterClsid, "Ptr", 0, "Ptr*", 0, "Ptr*", IFilter) != 0 ) ; ILoadFilter::LoadIFilter + ExitApp +if (IsFunc("Guid_ToStr")) + MsgBox % Guid_ToStr(FilterClsid) +ObjRelease(FilterRegistration) + +if (DllCall("shlwapi\SHCreateStreamOnFile", "Str", file, "UInt", STGM_READ, "Ptr*", iStream) != 0 ) + ExitApp +PersistStream := ComObjQuery(IFilter, "{00000109-0000-0000-C000-000000000046}") +if (DllCall(NumGet(NumGet(PersistStream+0)+5*A_PtrSize), "Ptr", PersistStream, "Ptr", iStream) != 0 ) ; ::Load + ExitApp +ObjRelease(iStream) + +status := 0 +if (DllCall(NumGet(NumGet(IFilter+0)+3*A_PtrSize), "Ptr", IFilter, "UInt", IFILTER_INIT_DISABLE_EMBEDDED | IFILTER_INIT_INDEXING_ONLY, "Int64", 0, "Ptr", 0, "Int64*", status) != 0 ) ; IFilter::Init + ExitApp + +VarSetCapacity(STAT_CHUNK, A_PtrSize == 8 ? 64 : 52) +VarSetCapacity(buf, (cchBufferSize * 2) + 2) +while (DllCall(NumGet(NumGet(IFilter+0)+4*A_PtrSize), "Ptr", IFilter, "Ptr", &STAT_CHUNK) == 0) { ; ::GetChunk + if (NumGet(STAT_CHUNK, 8, "UInt") & CHUNK_TEXT) { + while (DllCall(NumGet(NumGet(IFilter+0)+5*A_PtrSize), "Ptr", IFilter, "Int64*", (siz := cchBufferSize), "Ptr", &buf) != FILTER_E_NO_MORE_TEXT) ; ::GetText + { + text := StrGet(&buf,, "UTF-16") + if (resultstriplinebreaks) + text := StrReplace(text, "`r`n") + if (InStr(text, searchstring)) { + MsgBox "%searchstring%" found + break + } + } + } +} +ObjRelease(PersistStream) +ObjRelease(iFilter) +if (job) + DllCall("CloseHandle", "Ptr", job) + +ExitApp \ No newline at end of file diff --git a/InternetExplorerCaretBrowsingEnabledForPage.ahk b/InternetExplorerCaretBrowsingEnabledForPage.ahk new file mode 100644 index 0000000..3d6871b --- /dev/null +++ b/InternetExplorerCaretBrowsingEnabledForPage.ahk @@ -0,0 +1,50 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +; Select an Internet Explorer tab and press q while this script is running + +OLECMDF_SUPPORTED := 0x1 +OLECMDF_ENABLED := 0x2 +OLECMDF_LATCHED := 0x4 + +VarSetCapacity(CGID_MSHTML, 16) +DllCall("ole32\CLSIDFromString", "WStr", "{de4ba900-59ca-11cf-9592-444553540000}", "Ptr", &CGID_MSHTML) + +q:: +oWB := WBGet("ahk_id " . WinExist("A")) +; https://msdn.microsoft.com/en-us/library/cc849093(v=vs.85).aspx +IOleCommandTarget := ComObjQuery(oWB.Document, "{b722bccb-4e68-101b-a2bc-00aa00404770}") +VarSetCapacity(OLECMD, 8, 0), NumPut(IDM_CARETBROWSINGMODE := 2436, OLECMD,, "UInt") +if (DllCall(NumGet(NumGet(IOleCommandTarget+0)+3*A_PtrSize), "Ptr", IOleCommandTarget, "Ptr", &CGID_MSHTML, "UInt", 1, "Ptr", &OLECMD, "Ptr", 0) >= 0) + MsgBox % "Caret browsing active: " . (NumGet(OLECMD, 4, "UInt") & OLECMDF_LATCHED ? "True" : "False") + +newSetting := -1 ; -1: toggle, False: disable, True:enable +if (newSetting == -1) { + pVar := 0 +} else { + VarSetCapacity(VARIANT, 24, 0) + NumPut(VT_BOOL := 11, VARIANT,, "UShort") + NumPut(newSetting ? -1 : False, VARIANT, 8, "Short") + pVar := &VARIANT +} +DllCall(NumGet(NumGet(IOleCommandTarget+0)+4*A_PtrSize), "Ptr", IOleCommandTarget, "Ptr", &CGID_MSHTML, "UInt", IDM_CARETBROWSINGMODE, "UInt", OLECMDEXECOPT_DONTPROMPTUSER := 2, "Ptr", pVar, "Ptr", 0) +ObjRelease(IOleCommandTarget) +oWB := "" +return + +;[WBGet function for AHK v1.1] +;WBGet function - AutoHotkey Community +;https://autohotkey.com/boards/viewtopic.php?f=6&t=39869 + +WBGet(WinTitle="ahk_class IEFrame", Svr#=1) { ;// based on ComObjQuery docs + static msg := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT") + , IID := "{0002DF05-0000-0000-C000-000000000046}" ;// IID_IWebBrowserApp +;// , IID := "{332C4427-26CB-11D0-B483-00C04FD90119}" ;// IID_IHTMLWindow2 + SendMessage msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle% + if (ErrorLevel != "FAIL") { + lResult:=ErrorLevel, VarSetCapacity(GUID,16,0) + if DllCall("ole32\CLSIDFromString", "wstr","{332C4425-26CB-11D0-B483-00C04FD90119}", "ptr",&GUID) >= 0 { + DllCall("oleacc\ObjectFromLresult", "ptr",lResult, "ptr",&GUID, "ptr",0, "ptr*",pdoc) + return ComObj(9,ComObjQuery(pdoc,IID,IID),1), ObjRelease(pdoc) + } + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..eb3be45 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 qwerty12 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LaptopBrightnessSetter/README.md b/LaptopBrightnessSetter/README.md new file mode 100644 index 0000000..ca0b384 --- /dev/null +++ b/LaptopBrightnessSetter/README.md @@ -0,0 +1,25 @@ +Download from https://gist.github.com/qwerty12/4b3f41eb61724cd9e8f2bb5cc15c33c2 + +On Windows 10, it will set the laptop's monitor brightness and show the brightness OSD present there. + +Showing the OSD might be a bit iffy, however: +* On Windows 10, the OSD window responds to a SHELLHOOK message to show the OSD on demand. However, the window to send said message to doesn't exist until it's created by pressing the brightness/volume buttons (the former only available physically), or if an undocumented function provided by the shell over COM is called. To create the window if needed, this tries the latter first and then falls back to quickly muting/unmuting the volume. I suspect with every new Windows 10 service pack major update, the GUIDs needed to call the COM method will change, like how they did for the IPolicyConfig interface and "IVirtualDesktopManagerInternal". The SID and IID is correct for 14393.693. +* On Windows 8, I'm hoping the behaviour is the same, but I haven't checked +* On Windows 7, there is no OSD to speak of + +To use, paste the contents of the Gist into your file or save the raw contents of the Gist as something like, say, BrightnessSetter.ahk in a default AutoHotkey library folder. And then do something like this: + + #include ; if you saved the class as its own file + BrightnessSetter.SetBrightness(-10) + +If an own instance of the BrightnessSetter class is created, then it will monitor the AC insertion state. That's optional, however. + +There's really only one method that actually does anything, the SetBrightness method. Its parameters: +* increment - how much to increase or decrease the current brightness by. If jump is set, then increment is considered to be an absolute value +* jump - sets the brightness directly instead of working relatively with the current brightness value. False by default +* showOSD - determines if the OSD should be shown. To match the behaviour of the physical brightness keys, BrightnessSetter shows the OSD regardless of whether the brightness was actually changed. True by default +* autoDcOrAc - set to -1 if you want BrightnessSetter to determine the power source and set the brightness for the active power source, 0 if you want the brightness value for when battery power is active to be changed, and 1 for the brightness value when a charger is plugged in. -1 by default +* forceDifferentScheme - by default, BrightnessSetter works on the active power plan. If you want the brightness for a non-active power plan to be set, you can pass a pointer to the appropriate GUID structure for it. Linear Spoon has an excellent post here on using PowerEnumerate to get all the power plans on the system along with their GUIDs. 0 by default to force using the active scheme + +Credits: +* YashMaster for the shellhook mechanism and brightness validity tests I pretty much copied (and possibly messed up): https://github.com/YashMaster/Tweaky diff --git a/LoadAdBlockPlusForIEintoAHK.ahk b/LoadAdBlockPlusForIEintoAHK.ahk new file mode 100644 index 0000000..a982fdb --- /dev/null +++ b/LoadAdBlockPlusForIEintoAHK.ahk @@ -0,0 +1,9 @@ +try if ((BhoAbp := ComObjCreate("{FFCB3198-32F3-4E8B-9539-4324694ED664}", "{FC4801A3-2BA9-11CF-A229-00AA003D7352}"))) { + DllCall(NumGet(NumGet(BhoAbp+0)+3*A_PtrSize), "Ptr", BhoAbp, "Ptr", wb) +} +... +if (BhoAbp) { + ; When it's time to release the your ActiveX WebBrowser object: + DllCall(NumGet(NumGet(BhoAbp+0)+3*A_PtrSize), "Ptr", BhoAbp, "Ptr", 0) + ObjRelease(BhoAbp) +} \ No newline at end of file diff --git a/LogoffAllUsersExceptYou.ahk b/LogoffAllUsersExceptYou.ahk new file mode 100644 index 0000000..e81dc06 --- /dev/null +++ b/LogoffAllUsersExceptYou.ahk @@ -0,0 +1,49 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +full_command_line := DllCall("GetCommandLine", "str") + +if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)")) +{ + try + { + if A_IsCompiled + Run *RunAs "%A_ScriptFullPath%" /restart + else + Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%" + } + ExitApp +} +LogonDesktop_ProcessIdToSessionId(LogonDesktop_GetCurrentProcessId(), scriptProcessSessionId) + +if ((wtsapi32 := DllCall("LoadLibrary", "Str", "wtsapi32.dll", "Ptr"))) { + if (DllCall("wtsapi32\WTSEnumerateSessionsEx", "Ptr", WTS_CURRENT_SERVER_HANDLE := 0, "UInt*", 1, "UInt", 0, "Ptr*", pSessionInfo, "UInt*", wtsSessionCount)) { + WTS_CONNECTSTATE_CLASS := {0: "WTSActive", 1: "WTSConnected", 2: "WTSConnectQuery", 3: "WTSShadow", 4: "WTSDisconnected", 5: "WTSIdle", 6: "WTSListen", 7: "WTSReset", 8: "WTSDown", 9: "WTSInit"} + cbWTS_SESSION_INFO_1 := A_PtrSize == 8 ? 56 : 32 + Loop % wtsSessionCount { + currSessOffset := cbWTS_SESSION_INFO_1 * (A_Index - 1) ;, ExecEnvId := NumGet(pSessionInfo+0, currSessOffset, "UInt") + currSessOffset += 4, State := NumGet(pSessionInfo+0, currSessOffset, "UInt") + currSessOffset += 4, SessionId := NumGet(pSessionInfo+0, currSessOffset, "UInt") + currSessOffset += A_PtrSize ; , SessionName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr")) + currSessOffset += A_PtrSize ;, HostName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr")) +; currSessOffset += A_PtrSize, UserName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr")) +; currSessOffset += A_PtrSize, DomainName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr")) +; currSessOffset += A_PtrSize, FarmName := StrGet(NumGet(pSessionInfo+0, currSessOffset, "Ptr")) + + if (SessionId && SessionId != scriptProcessSessionId) + DllCall("wtsapi32\WTSLogoffSession", "Ptr", WTS_CURRENT_SERVER_HANDLE, "UInt", SessionId, "Int", False) + } + DllCall("wtsapi32\WTSFreeMemoryEx", "UInt", WTSTypeSessionInfoLevel1 := 2, "Ptr", pSessionInfo, "UInt", wtsSessionCount) + } + DllCall("FreeLibrary", "Ptr", wtsapi32) +} + +LogonDesktop_GetCurrentProcessId() { + static dwProcessId := DllCall("GetCurrentProcessId", "UInt") ; well, it's not like this one is going to change each time we call it + return dwProcessId +} + +LogonDesktop_ProcessIdToSessionId(dwProcessId, ByRef dwSessionId) +{ + static ProcessIdToSessionId := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandleW", "WStr", "kernel32.dll", "Ptr"), "AStr", "ProcessIdToSessionId", "Ptr") + return DllCall(ProcessIdToSessionId, "UInt", dwProcessId, "UInt*", dwSessionId) +} \ No newline at end of file diff --git a/MoveAHKGuiToDifferentWindows10VirtualDesktop.ahk b/MoveAHKGuiToDifferentWindows10VirtualDesktop.ahk new file mode 100644 index 0000000..e123671 --- /dev/null +++ b/MoveAHKGuiToDifferentWindows10VirtualDesktop.ahk @@ -0,0 +1,66 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +; #Warn ; Enable warnings to assist with detecting common errors. +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. +#NoTrayIcon +#SingleInstance force + +; Create multiple Windows 10 virtual desktops first + +; base script by k1dr0ck + +gui, +AlwaysOnTop +HwndhwndGui +gui, add, button, x10 y5 h20 w35 gsub1, <- +gui, add, button, x55 y5 h20 w35 gsub2, -> +gui, show, x15 y680 h30 w100 + +return + +sub1: + { + SendInput ^#{Left} + movewindow(hwndGui) + } +return + +sub2: + { + SendInput ^#{Right} + movewindow(hwndGui) + } +return + +guiclose: + { + exitapp + } +return + +movewindow(guiHwnd) +{ + static desktopID + if (!VarSetCapacity(desktopID)) + VarSetCapacity(desktopID, 16) + + try if IVirtualDesktopManager := ComObjCreate("{aa509086-5ca9-4c25-8f95-589d3c07b48a}", "{a5cd92ff-29be-454c-8d04-d82879fb3f1b}") { + Loop 10 { ; wait to see until our main GUI is not on the starting virtual desktop + hr := DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 3 * A_PtrSize), "Ptr", IVirtualDesktopManager, "Ptr", guiHwnd, "Int*", onCurrentDesktop) + if (hr == "" || hr < 0) { + ObjRelease(IVirtualDesktopManager) + return + } + Sleep 100 + if (!onCurrentDesktop) + break + } + if (!onCurrentDesktop) { + gui tmp: +Hwndwtfms ; create a new temporary GUI belonging to our process on the new virtual desktop + gui tmp: show + hr := DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 4 * A_PtrSize), "Ptr", IVirtualDesktopManager, "Ptr", wtfms, "Ptr", &desktopID) ; get the GUID of the virtual desktop hosting our temporary window + Gui tmp: destroy + if (hr == 0 && DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 5 * A_PtrSize), "Ptr", IVirtualDesktopManager, "Ptr", guiHwnd, "Ptr", &desktopID) == 0) ; move the main window to the same desktop + WinActivate ahk_id %guiHwnd% ; re-activate the window + } + ObjRelease(IVirtualDesktopManager) + } +} \ No newline at end of file diff --git a/MultiFileProperties.ahk b/MultiFileProperties.ahk new file mode 100644 index 0000000..460f66d --- /dev/null +++ b/MultiFileProperties.ahk @@ -0,0 +1,44 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. + +; Shows the same thing that you get when you select more than one file and view their combined properties + +; Credits: Remy Lebeau: https://stackoverflow.com/a/34551988 + +MultiFileProperties(filenames*) { + static IID_IDataObject + if (!VarSetCapacity(IID_IDataObject)) + VarSetCapacity(IID_IDataObject, 16), DllCall("ole32\CLSIDFromString", "WStr", "{0000010e-0000-0000-C000-000000000046}", "Ptr", &IID_IDataObject) + + ret := False + if (!filenames.MaxIndex()) + return ret + + DllCall("shell32\SHGetDesktopFolder", "Ptr*", pDesktop) + if (!pDesktop) + return ret + + VarSetCapacity(pidl_list, filenames.MaxIndex() * A_PtrSize) + filenameCount := 0, ParseDisplayName := NumGet(NumGet(pDesktop+0)+3*A_PtrSize) + for _, filename in filenames + filenameCount += DllCall(ParseDisplayName, "Ptr", pDesktop, "Ptr", 0, Ptr, 0, "WStr", filename, "Ptr", 0, "Ptr", &pidl_list+(filenameCount * A_PtrSize), "Ptr", 0) == 0 + + if (filenameCount && DllCall(NumGet(NumGet(pDesktop+0)+10*A_PtrSize), "Ptr", pDesktop, "Ptr", 0, "UInt", filenameCount, "Ptr", &pidl_list, "Ptr", &IID_IDataObject, "Ptr", 0, "Ptr*", pDataObject) == 0) { ; GetUIObjectOf + ret := DllCall("shell32\SHMultiFileProperties", "Ptr", pDataObject, "UInt", 0) == 0 + ObjRelease(pDataObject) + } + + loop %filenameCount% { + if ((pidl := NumGet(pidl_list, (A_Index - 1) * A_PtrSize, "Ptr"))) + DllCall("ole32\CoTaskMemFree", "Ptr", pidl) + } + ObjRelease(pDesktop) + + return ret +} + +if (MultiFileProperties(A_ProgramFiles . "\Internet Explorer\iexplore.exe", A_WinDir . "\Explorer.exe", A_ScriptFullPath)) { + MsgBox Wait for the properties window and then click OK here when done to end the script +} else { + MsgBox Error +} \ No newline at end of file diff --git a/OneDriveOnDemandSyncToggle/OneDriveOnDemandSyncToggle.ahk b/OneDriveOnDemandSyncToggle/OneDriveOnDemandSyncToggle.ahk new file mode 100644 index 0000000..ea45485 --- /dev/null +++ b/OneDriveOnDemandSyncToggle/OneDriveOnDemandSyncToggle.ahk @@ -0,0 +1,117 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +#NoTrayIcon + +MODE_GET_STATUS := 0 +,MODE_TOGGLE_KEEP_ON_DEVICE := 1 +,MODE_FREE_SPACE := 2 + +mode := MODE_GET_STATUS + +if 0 < 1 +{ + MsgBox This script requires at least 1 incoming parameter. + ExitApp 1 +} +else if 0 = 2 +{ + firstParam = %1% + if (firstParam = "/keepondevice") + mode := MODE_TOGGLE_KEEP_ON_DEVICE + else if (firstParam = "/freespace") + mode := MODE_FREE_SPACE + else + ExitApp 1 +} +else if 0 > 2 +{ + ExitApp 1 +} + +RegRead, UserFolder, HKEY_CURRENT_USER\Software\Microsoft\OneDrive, UserFolder +if (ErrorLevel || !InStr(FileExist(UserFolder), "D")) + ExitApp 1 +SetWorkingDir %UserFolder% + +if (mode == MODE_GET_STATUS) + filenameParam = %1% +else + filenameParam = %2% +if (!FileExist(filenameParam)) + ExitApp 1 + +VarSetCapacity(dwTypeData, 2050) +,VarSetCapacity(IID_IDataObject, 16) +,DllCall("ole32\CLSIDFromString", "WStr", "{0000010e-0000-0000-C000-000000000046}", "Ptr", &IID_IDataObject) + +DoOrDie(DllCall("shell32\SHGetDesktopFolder", "Ptr*", pDesktop)) +filenames := [DllCall("shlwapi\PathCombineW", "Ptr", &dwTypeData, "Ptr", &UserFolder, "Ptr", &filenameParam, "WStr")] +VarSetCapacity(pidl_list, filenames.MaxIndex() * A_PtrSize) +filenameCount := 0, ParseDisplayName := NumGet(NumGet(pDesktop+0)+3*A_PtrSize) +for _, filename in filenames + filenameCount += DllCall(ParseDisplayName, "Ptr", pDesktop, "Ptr", 0, Ptr, 0, "WStr", filename, "Ptr", 0, "Ptr", &pidl_list+(filenameCount * A_PtrSize), "Ptr", 0) >= 0x00 +if (!filenameCount) + ExitApp 1 +DoOrDie(DllCall(NumGet(NumGet(pDesktop+0)+10*A_PtrSize), "Ptr", pDesktop, "Ptr", 0, "UInt", filenameCount, "Ptr", &pidl_list, "Ptr", &IID_IDataObject, "Ptr", 0, "Ptr*", pDataObject)) + +fsctxmenu := ComObjCreate("{CB3D0F55-BC2C-4C1A-85ED-23ED75B5106B}", "{000214E4-0000-0000-C000-000000000046}") +fsshextinit := ComObjQuery(fsctxmenu, "{000214E8-0000-0000-C000-000000000046}") +DoOrDie(DllCall(NumGet(NumGet(fsshextinit+0)+3*A_PtrSize), "Ptr", fsshextinit, "Ptr", 0, "Ptr", pDataObject, "Ptr", 0)) + +DoOrDie(DllCall(NumGet(NumGet(fsctxmenu+0)+3*A_PtrSize), "Ptr", fsctxmenu, "Ptr", (hMenu := DllCall("CreatePopupMenu", "Ptr")), "UInt", 0, "UInt", 0, "UInt", 0x7FFF, "UInt", 0x00000080)) +VarSetCapacity(MENUITEMINFOW, (cbMENUITEMINFOW := A_PtrSize == 8 ? 72 : 44)) +Loop % DllCall("GetMenuItemCount", "Ptr", hMenu, "Int") { + DllCall("ntdll\RtlZeroMemory", "Ptr", &MENUITEMINFOW, "Ptr", cbMENUITEMINFOW) + ,NumPut(cbMENUITEMINFOW, MENUITEMINFOW, 0, "UInt") + ,NumPut(0x00000002 | 0x00000001 | 0x00000040, MENUITEMINFOW, 4, "UInt") + ,NumPut(1024, MENUITEMINFOW, A_PtrSize == 8 ? 64 : 40, "UInt") + ,NumPut(&dwTypeData, MENUITEMINFOW, A_PtrSize == 8 ? 56 : 36, "Ptr") + if ((DllCall("GetMenuItemInfo", "Ptr", hMenu, "UInt", A_Index - 1, "Int", True, "Ptr", &MENUITEMINFOW, "Int")) && (cch := NumGet(MENUITEMINFOW, A_PtrSize == 8 ? 64 : 40, "UInt"))) { + fState := NumGet(MENUITEMINFOW, 12, "UInt") + ,idn := NumGet(MENUITEMINFOW, 16, "UInt") + ,menulabel := StrGet(&dwTypeData, cch, "UTF-16") + if (menulabel == "Always keep on this device") { + if (mode == MODE_GET_STATUS) + msg .= (StrLen(msg) ? "`n" : "") . filenameParam . " is " . (fState & 0x00000008 != 0x00000008 ? "not " : "") . "set to always be kept on this device" + else if (mode == MODE_TOGGLE_KEEP_ON_DEVICE) + break + } else if (menulabel == "Free up space") { + cannotBeSelected := fState & 0x00000001 || fState & 0x00000002 + if (mode == MODE_GET_STATUS) { + msg .= (StrLen(msg) ? "`n" : "") . filenameParam . " can" . (cannotBeSelected ? "not " : " ") . "be freed to make space" + } else if (mode == MODE_FREE_SPACE) { + if (cannotBeSelected) + mode := -1 + break + } + } + } +} + +if (mode == MODE_GET_STATUS) { + msgbox %msg% +} else if (mode == MODE_TOGGLE_KEEP_ON_DEVICE || mode == MODE_FREE_SPACE) { + VarSetCapacity(info, (cbCMINVOKECOMMANDINFO := A_PtrSize == 8 ? 56 : 36), 0) + ,NumPut(cbCMINVOKECOMMANDINFO, info, 0, "UInt") + ,NumPut(0x00000100, info, 4, "UInt") + ,NumPut(A_ScriptHwnd, info, 8, "Ptr") + ,NumPut(idn, info, A_PtrSize == 8 ? 16 : 12, "UPtr") + ,DoOrDie(DllCall(NumGet(NumGet(fsctxmenu+0)+4*A_PtrSize), "Ptr", fsctxmenu, "Ptr", &info)) ; IContextMenu::InvokeCommand + Sleep -1 +} + +DllCall("DestroyMenu", "Ptr", hMenu) +,ObjRelease(fsshextinit) +,ObjRelease(fsctxmenu) +,ObjRelease(pDataObject) +Loop %filenameCount% { + if ((pidl := NumGet(pidl_list, (A_Index - 1) * A_PtrSize, "Ptr"))) + DllCall("ole32\CoTaskMemFree", "Ptr", pidl) +} +ObjRelease(pDesktop) +ExitApp + +DoOrDie(hr) +{ + if (hr == "" || hr < 0) + ExitApp 1 +} \ No newline at end of file diff --git a/OneDriveOnDemandSyncToggle/README.md b/OneDriveOnDemandSyncToggle/README.md new file mode 100644 index 0000000..e786545 --- /dev/null +++ b/OneDriveOnDemandSyncToggle/README.md @@ -0,0 +1,12 @@ +WARNING: I do not use OneDrive myself. I have not tested this with any file over 200 KB... *Make sure you have backups of any important files stored outside of OneDrive!* + +A hack that loads the OneDrive context menu shell extension into AutoHotkey, where AHK can then select menu items directly - the extension tells the OneDrive client to perform the action. + +To find out if a file is set to always remain stored on your PC and/or whether the space used (if any) by said file can be freed, run the script with just the target's filename as the script's sole argument. `Example: Untitled.ahk "Documents\New Text Document.txt"` + +To toggle a file's always-remain-on-your-PC status, run the script with /keepondevice as the first argument, followed by the target's filename as the second argument. Example: `Untitled.ahk /keepondevice "Documents\New Text Document.txt"` + +To have a file cleared from your PC, run the script with /freespace as the first argument, followed by the target's filename as the second argument. Example: `Untitled.ahk /freespace "Documents\New Text Document.txt"` + +* This is the bare minimum to do something like this this way. Adding in support to toggle multiple files' always-remain-on-your-PC status / freeing multiple files is probably possible by reworking my bad command-line logic and adding the extra filenames to the filenames array. + * But not for the getting a file's current status operation! Select multiple files in your OneDrive folder of varying sync statuses, right-click and observe the inconsistencies. This script determines the current status for one file by seeing if the relevant menu is (un)checked / enabled / disabled. Yeah... diff --git a/PopupMenuUtils.ahk b/PopupMenuUtils.ahk new file mode 100644 index 0000000..8caf73d --- /dev/null +++ b/PopupMenuUtils.ahk @@ -0,0 +1,77 @@ +; https://autohotkey.com/board/topic/16457-controlling-popup-menues/ + +PopupMenuUtils_user32_handle(fn) +{ + static u32 := DllCall("GetModuleHandle", Str, "user32.dll", "Ptr") + return DllCall("GetProcAddress", "Ptr", u32, "AStr", fn, "Ptr") +} + +PopupMenuUtils_MF_BYPOSITION() { + return 0x00000400 +} + +PopupMenuUtils_GetMenuItemCount(hMenu) +{ + static GetMenuItemCount := PopupMenuUtils_user32_handle("GetMenuItemCount") + return DllCall(GetMenuItemCount, "Ptr", hMenu, "Int") +} + +;PopupMenuUtils_GetMenuString(hMenu, nPos) +;{ +; static GetMenuStringW := PopupMenuUtils_user32_handle("GetMenuStringW"), byp := PopupMenuUtils_MF_BYPOSITION() +; if ((hMenu) && (length := DllCall(GetMenuStringW, "Ptr", hMenu, "UInt", nPos, "Ptr", 0, "Int", 0, "UInt", byp))) { +; length += 1, VarSetCapacity(lpString, (length * 2) + 2) +; if (DllCall(GetMenuStringW, "Ptr", hMenu, "UInt", nPos, "WStr", lpString, "Int", length, "UInt", byp)) +; return lpString +; } +; return "" +;} + +PopupMenuUtils_GetMenuString(hMenu, nPos) +{ + static lpString, GetMenuStringW := PopupMenuUtils_user32_handle("GetMenuStringW"), byp := PopupMenuUtils_MF_BYPOSITION() + if !VarSetCapacity(lpString) + VarSetCapacity(lpString, 1024) ; what sort of idiot makes a menu item have ~510 characters, anyway? + if (DllCall(GetMenuStringW, "Ptr", hMenu, "UInt", nPos, "WStr", lpString, "Int", 511, "UInt", byp)) + return lpString +} + +PopupMenuUtils_GetMenuState(hMenu, nPos) +{ + static GetMenuState := PopupMenuUtils_user32_handle("GetMenuState"), byp := PopupMenuUtils_MF_BYPOSITION() + return DllCall(GetMenuState, "Ptr", hMenu, "UInt", nPos, "UInt", byp, "UInt") +} + +PopupMenuUtils_ItemIsChecked(State) { + return !!(State & 0x00000008) ; MF_CHECKED +} + +PopupMenuUtils_ItemIsDisabled(State) { + return !!(State & 0x00000002 || State & 0x00000001) ; MF_DISABLED || MF_GRAYED +} + +PopupMenuUtils_ItemIsPopup(State) { + return !!(State & 0x00000010) ; MF_POPUP +} + +PopupMenuUtils_GetMenuItemID(hMenu, nPos) { + return DllCall("GetMenuItemID", "Ptr", hMenu, "int", nPos, "UInt") +} + +PopupMenuUtils_GetHmenuFromHwnd(hWnd) +{ + static SendMessagePtr := PopupMenuUtils_user32_handle(A_IsUnicode ? "SendMessageW" : "SendMessageA") + return DllCall(SendMessagePtr, "Ptr", hWnd, "UInt", 0x01E1, "Ptr", 0, "Ptr", 0, "Ptr") ; MN_GETHMENU +} + +PopupMenuUtils_GetMenu(hwnd) { + return DllCall("GetMenu", "Ptr", hwnd, "Ptr") +} + +PopupMenuUtils_GetSubmenu(hMenu, nPos) { + return DllCall("GetSubMenu", "Ptr", hMenu, "int", nPos, "Ptr") +} + +PopupMenuUtils_WinHasMenu(WinTitle:="") { + return !!PopupMenuUtils_GetMenu(WinExist(WinTitle)) +} diff --git a/ProcessIsSuspended.ahk b/ProcessIsSuspended.ahk new file mode 100644 index 0000000..de99121 --- /dev/null +++ b/ProcessIsSuspended.ahk @@ -0,0 +1,55 @@ +#NoEnv + +; Taken from the Process Hacker source code, by wj32 and dmex +; Thanks to jeeswg for fixing the 32-bit incompatibility + +ProcessIsSuspended(pid, ByRef isPartiallySuspended := 0) { + static initialBufferSize := 0x4000, cbSYSTEM_THREAD_INFORMATION := A_PtrSize == 8 ? 80 : 64 + static SystemProcessInformation := 5, STATUS_BUFFER_TOO_SMALL := 0xC0000023, STATUS_INFO_LENGTH_MISMATCH := 0xC0000004 + static Waiting := 5, Suspended := 5 + static UniqueProcessIdOffset := A_PtrSize == 8 ? 80 : 68, NumberOfThreadsOffset := 4, ThreadsArrayOffset := A_PtrSize == 8 ? 256 : 184 + static ThreadStateOffset := A_PtrSize == 8 ? 68 : 52, WaitReasonOffset := A_PtrSize == 8 ? 72 : 56 + bufferSize := initialBufferSize + + VarSetCapacity(ProcessBuffer, bufferSize) + + Loop { + status := DllCall("ntdll\NtQuerySystemInformation", "UInt", SystemProcessInformation, "Ptr", &ProcessBuffer, "UInt", bufferSize, "UInt*", bufferSize, "UInt") + if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) { + VarSetCapacity(ProcessBuffer, bufferSize) + } + else { + break + } + } + + if (status < 0) { + return -1 + } + + if (bufferSize <= 0x100000) initialBufferSize := bufferSize + + isSuspended := pid > 0 + isPartiallySuspended := False + ThisEntryOffset := 0 + + Loop { + if (NumGet(ProcessBuffer, ThisEntryOffset + UniqueProcessIdOffset, "Ptr") == pid) { + Loop % NumGet(ProcessBuffer, ThisEntryOffset + NumberOfThreadsOffset, "UInt") { + ThisThreadsOffset := ThisEntryOffset + ThreadsArrayOffset + (cbSYSTEM_THREAD_INFORMATION * (A_Index - 1)) + ThreadState := NumGet(ProcessBuffer, ThisThreadsOffset + ThreadStateOffset, "UInt") + WaitReason := NumGet(ProcessBuffer, ThisThreadsOffset + WaitReasonOffset, "UInt") + if (ThreadState != Waiting || WaitReason != Suspended) { + isSuspended := False + } else { + isPartiallySuspended := True + } + } + return isSuspended + } + } until (!(NextEntryOffset := NumGet(ProcessBuffer, ThisEntryOffset, "UInt")), ThisEntryOffset += NextEntryOffset) + + return -1 +} + +;MsgBox % ProcessIsSuspended(560) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c190498 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +Other scripts that might be of interest: + +* [Change the size of the quick launch deskband programmatically](https://autohotkey.com/boards/viewtopic.php?p=150599#p150599) + +* [Firefox native messaging example](https://autohotkey.com/boards/viewtopic.php?f=5&t=29308) + +* [Chrome native messaging example](https://autohotkey.com/boards/viewtopic.php?p=150461#p150461) + +* [Get selected filenames from open Open/Save file dialogs in other processes](https://autohotkey.com/boards/viewtopic.php?p=146043#p146043) + +* [Using IPolicyConfig to disable an audio device](https://autohotkey.com/boards/viewtopic.php?f=5&t=21229) + +* [Add cursor file as resource to exe](https://autohotkey.com/boards/viewtopic.php?f=5&t=8516) + diff --git a/SetGlobalWindowsTextToSpeechVoice.ahk b/SetGlobalWindowsTextToSpeechVoice.ahk new file mode 100644 index 0000000..cf685f1 --- /dev/null +++ b/SetGlobalWindowsTextToSpeechVoice.ahk @@ -0,0 +1,99 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +; https://autohotkey.com/boards/viewtopic.php?p=166239#p166239 + +if (SUCCEEDED(SpGetCategoryFromId(SPCAT_VOICES := "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices", cpSpObjectTokenCategory))) +{ + hr := DllCall(NumGet(NumGet(cpSpObjectTokenCategory+0)+18*A_PtrSize), "Ptr", cpSpObjectTokenCategory, "Ptr", 0, "Ptr", 0, "Ptr*", cpSpEnumTokens) + + if (SUCCEEDED(hr)) + { + hr := DllCall(NumGet(NumGet(cpSpEnumTokens+0)+8*A_PtrSize), "Ptr", cpSpEnumTokens, "UInt*", tokenCount) + if (SUCCEEDED(hr)) + { + voices := Object() + Loop %tokenCount% { + hr := DllCall(NumGet(NumGet(cpSpEnumTokens+0)+7*A_PtrSize), "Ptr", cpSpEnumTokens, "UInt", A_Index - 1, "Ptr*", pToken) + if (FAILED(hr)) { + MsgBox Bailing out + ExitApp 1 + } + hr := DllCall(NumGet(NumGet(pToken+0)+6*A_PtrSize), "Ptr", pToken, "Ptr", 0, "Ptr*", pszValue) + if (FAILED(hr)) { + MsgBox Bailing out + ExitApp 2 + } + hr := DllCall(NumGet(NumGet(pToken+0)+16*A_PtrSize), "Ptr", pToken, "Ptr*", pszCoMemTokenId) + if (FAILED(hr)) { + MsgBox Bailing out + ExitApp 3 + } + voices[StrGet(pszCoMemTokenId, "UTF-16")] := StrGet(pszValue, "UTF-16") + DllCall("ole32\CoTaskMemFree", "Ptr", pszValue) + DllCall("ole32\CoTaskMemFree", "Ptr", pszCoMemTokenId) + ObjRelease(pToken) + } + prompt := "Pick a voice by its number:" + for k, v in voices + prompt .= "`r`n" . A_Index . ": " v + InputBox, TheChosenOne,, %prompt% + if (ErrorLevel == 0) { + for k, v in voices { + if (A_Index == TheChosenOne) { + hr := DllCall(NumGet(NumGet(cpSpObjectTokenCategory+0)+19*A_PtrSize), "Ptr", cpSpObjectTokenCategory, "WStr", k) + break + } + } + } + } + ObjRelease(cpSpEnumTokens) + } + + ObjRelease(cpSpObjectTokenCategory) +} + +SpGetCategoryFromId(pszCategoryId, ByRef ppCategory, fCreateIfNotExist := False) +{ + static CLSID_SpObjectTokenCategory := "{A910187F-0C7A-45AC-92CC-59EDAFB77B53}" + ,ISpObjectTokenCategory := "{2D3D3845-39AF-4850-BBF9-40B49780011D}" + + hr := 0 + try { + cpTokenCategory := ComObjCreate(CLSID_SpObjectTokenCategory, ISpObjectTokenCategory) + } catch e { + ; No, A_LastError or ErrorLevel doesn't contain the error code on its own and I CBA to use CoCreateInstance directly + if (RegExMatch(e.Message, "0[xX][0-9a-fA-F]+", errCode)) { ; https://stackoverflow.com/a/9221391 + hr := errCode + 0 + } else { + hr := 0x80004005 + } + } + + if (SUCCEEDED(hr)) + { + hr := DllCall(NumGet(NumGet(cpTokenCategory+0)+15*A_PtrSize), "Ptr", cpTokenCategory, "WStr", pszCategoryId, "Int", fCreateIfNotExist) + } + + if (SUCCEEDED(hr)) + { + ppCategory := cpTokenCategory + } + else + { + if (cpTokenCategory) + ObjRelease(cpTokenCategory) + } + + return hr +} + +; https://github.com/maul-esel/AHK-Util-Funcs/blob/master/FAILED.ahk +SUCCEEDED(hr) +{ + return hr != "" && hr >= 0x00 +} + +FAILED(hr) +{ + return hr == "" || hr < 0 +} \ No newline at end of file diff --git a/SetRestrictedProcessDacl.ahk b/SetRestrictedProcessDacl.ahk new file mode 100644 index 0000000..94adc7e --- /dev/null +++ b/SetRestrictedProcessDacl.ahk @@ -0,0 +1,72 @@ +SetRestrictedProcessDacl() +{ + ret := False + + hCurProc := DllCall("GetCurrentProcess", "Ptr") + if (!DllCall("advapi32\OpenProcessToken", "Ptr", hCurProc, "UInt", TOKEN_QUERY := 0x0008, "Ptr*", hToken)) + return ret + + if (!_GetTokenInformation(hToken, TokenUser := 1, 0, 0, dwLengthNeeded)) + if (A_LastError == 122 && VarSetCapacity(TOKEN_USER, dwLengthNeeded)) ; ERROR_INSUFFICIENT_BUFFER + if (_GetTokenInformation(hToken, TokenUser, &TOKEN_USER, dwLengthNeeded, dwLengthNeeded)) { + SECURITY_MAX_SID_SIZE := 68 + SIDs := {"WinWorldSid": "1", "WinLocalSystemSid": "22", "WinBuiltinAdministratorsSid": "26"} + for k, v in SIDs { + SIDs.SetCapacity(k, (cbSid := SECURITY_MAX_SID_SIZE)) + if (!DllCall("advapi32\CreateWellKnownSid", "UInt", v+0, "Ptr", 0, "Ptr", SIDs.GetAddress(k), "UInt*", cbSid)) { + DllCall("CloseHandle", "Ptr", hToken) + return ret + } + } + + EA := [{ "grfAccessPermissions": PROCESS_ALL_ACCESS := (STANDARD_RIGHTS_REQUIRED := 0x000F0000) | (SYNCHRONIZE := 0x00100000) | 0xFFFF ; 0xFFF for XP and 2000 + ,"grfAccessMode": GRANT_ACCESS := 1 + ,"grfInheritance": NO_INHERITANCE := 0 + ,"TrusteeForm": TRUSTEE_IS_SID := 0 + ,"TrusteeType": TRUSTEE_IS_WELL_KNOWN_GROUP := 5 + ,"ptstrName": SIDs.GetAddress("WinLocalSystemSid")} + ,{ "grfAccessPermissions": PROCESS_ALL_ACCESS + ,"grfAccessMode": GRANT_ACCESS + ,"grfInheritance": NO_INHERITANCE + ,"TrusteeForm": TRUSTEE_IS_SID + ,"TrusteeType": TRUSTEE_IS_WELL_KNOWN_GROUP + ,"ptstrName": SIDs.GetAddress("WinBuiltinAdministratorsSid")} + ,{ "grfAccessPermissions": PROCESS_QUERY_LIMITED_INFORMATION := 0x1000 | PROCESS_CREATE_PROCESS := 0x0080 + ,"grfAccessMode": GRANT_ACCESS + ,"grfInheritance": NO_INHERITANCE + ,"TrusteeForm": TRUSTEE_IS_SID + ,"TrusteeType": TRUSTEE_IS_USER := 1 + ,"ptstrName": NumGet(TOKEN_USER,, "Ptr")} ; user script is running under + ,{ "grfAccessPermissions": PROCESS_ALL_ACCESS + ,"grfAccessMode": DENY_ACCESS := 3 + ,"grfInheritance": NO_INHERITANCE + ,"TrusteeForm": TRUSTEE_IS_SID + ,"TrusteeType": TRUSTEE_IS_WELL_KNOWN_GROUP + ,"ptstrName": SIDs.GetAddress("WinWorldSid")}] + + padding := A_PtrSize == 8 ? 4 : 0 + cbEXPLICIT_ACCESS_W := (4 * 3) + padding + (A_PtrSize + (4 * 3) + padding + A_PtrSize) + VarSetCapacity(EXPLICIT_ACCESS_W, cbEXPLICIT_ACCESS_W * EA.MaxIndex(), 0) + for i, v in EA { + thisEA := cbEXPLICIT_ACCESS_W * (i - 1) + NumPut(v.grfAccessPermissions, EXPLICIT_ACCESS_W, thisEA, "UInt") + NumPut(v.grfAccessMode, EXPLICIT_ACCESS_W, thisEA + 4, "UInt") + NumPut(v.grfInheritance, EXPLICIT_ACCESS_W, thisEA + (4 * 2), "UInt") + NumPut(v.TrusteeForm, EXPLICIT_ACCESS_W, thisEA + ((4 * 3) + padding + A_PtrSize + 4), "UInt") + NumPut(v.TrusteeType, EXPLICIT_ACCESS_W, thisEA + ((4 * 3) + padding + A_PtrSize + (4 * 2)), "UInt") + NumPut(v.ptstrName, EXPLICIT_ACCESS_W, thisEA + ((4 * 3) + padding + A_PtrSize + (4 * 3) + padding), "Ptr") + } + + if (!DllCall("advapi32\SetEntriesInAcl", "UInt", EA.MaxIndex(), "Ptr", &EXPLICIT_ACCESS_W, "Ptr", 0, "Ptr*", pNewDacl)) { + ret := !DllCall("Advapi32\SetSecurityInfo", "Ptr", hCurProc, "UInt", SE_KERNEL_OBJECT := 6, "UInt", DACL_SECURITY_INFORMATION := 0x00000004, "Ptr", 0, "Ptr", 0, "Ptr", pNewDacl, "Ptr", 0) + DllCall("LocalFree", "Ptr", pNewDacl, "Ptr") + } + } + + DllCall("CloseHandle", "Ptr", hToken) + return ret +} + +_GetTokenInformation(TokenHandle, TokenInformationClass, ByRef TokenInformation, TokenInformationLength, ByRef ReturnLength, _tokenInfoType := "Ptr") { + return DllCall("advapi32\GetTokenInformation", "Ptr", TokenHandle, "UInt", TokenInformationClass, _tokenInfoType, TokenInformation, "UInt", TokenInformationLength, "UInt*", ReturnLength) +} \ No newline at end of file diff --git a/SetThemeFromdotThemeFile.ahk b/SetThemeFromdotThemeFile.ahk new file mode 100644 index 0000000..f157dee --- /dev/null +++ b/SetThemeFromdotThemeFile.ahk @@ -0,0 +1,21 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +; An alternative to selecting a .theme file by double-clicking on it and then closing the resulting personalisation window afterwards manually + +; Source: C:\Windows\diagnostics\system\AERO\CL_Utility.ps1 + +MsgBox This will change your Windows theme to Windows 7's classic one. Exit now from the tray menu if you do not want this. + +themePath := A_WinDir . "\Resources\Ease of Access Themes\classic.theme" ; Change as needed +if (FileExist(themePath)) +{ + try themeManager := ComObjCreate(CLSID_IThemeManager := "{C04B329E-5823-4415-9C93-BA44688947B0}", IID_IThemeManager := "{0646EBBE-C1B7-4045-8FD0-FFD65D3FC792}") + if (themeManager) { + themeBstr := DllCall("oleaut32\SysAllocString", "WStr", themePath, "Ptr") + if (themeBstr) { + DllCall(NumGet(NumGet(themeManager+0)+4*A_PtrSize), "Ptr", themeManager, "Ptr", themeBstr) ; ::ApplyTheme + DllCall("oleaut32\SysFreeString", "Ptr", themeBstr) + } + ObjRelease(themeManager) + } +} diff --git a/SetWindows10LockScreenPicture/README.txt b/SetWindows10LockScreenPicture/README.txt new file mode 100644 index 0000000..db37766 --- /dev/null +++ b/SetWindows10LockScreenPicture/README.txt @@ -0,0 +1,3 @@ +This is a script that uses the raw RT COM API directly to change your (i.e. the logged on user) Windows 10 lockscreen background picture. No dependencies other than Windows 10 and AutoHotkey itself. + +For something more robust, you might consider https://github.com/Sauler/PowershellUtils instead. \ No newline at end of file diff --git a/SetWindows10LockScreenPicture/SetWindows10LockScreenPicture.ahk b/SetWindows10LockScreenPicture/SetWindows10LockScreenPicture.ahk new file mode 100644 index 0000000..99dab3a --- /dev/null +++ b/SetWindows10LockScreenPicture/SetWindows10LockScreenPicture.ahk @@ -0,0 +1,71 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +; DllCall("ole32.dll\OleUninitialize") +; DllCall("combase.dll\RoInitialize", "UInt", RO_INIT_MULTITHREADED := 1) + +filename := "C:\Users\Me\Pictures\Wallpapers\affinity_street_romain_trystram_01.jpg" + +if (FileExist(filename)) { + ; 1. Create StorageFile obj for pic + VarSetCapacity(IIDStorageFileStatics, 16), VA_GUID(IIDStorageFileStatics := "{5984C710-DAF2-43C8-8BB4-A4D3EACFD03F}") + StorageFile := new HSTRING("Windows.Storage.StorageFile") + if (!DllCall("combase.dll\RoGetActivationFactory", "Ptr", StorageFile.str, "Ptr", &IIDStorageFileStatics, "Ptr*", instStorageFile)) { + if (!DllCall(NumGet(NumGet(instStorageFile+0)+6*A_PtrSize), "Ptr", instStorageFile, "Ptr", (_ := new HSTRING(filename)).str, "Ptr*", sfileasyncwrapper)) { + ; 2. Said SF obj gets created async. Keep checking (in a sync manner) to see if actual SF obj is created + ; Yes, this isn't a good way, but it's not like I usually expect COM objects to be returned async + sfileasyncinfo := ComObjQuery(sfileasyncwrapper, IID_IAsyncInfo := "{00000036-0000-0000-C000-000000000046}") + while (!DllCall(NumGet(NumGet(sfileasyncinfo+0)+7*A_PtrSize), "Ptr", sfileasyncinfo, "UInt*", status) && !status) + Sleep 100 + if (status != 1) + ExitApp 1 + ObjRelease(sfileasyncinfo) + + ; 3. It has! Finally take pointer to sf obj + DllCall(NumGet(NumGet(sfileasyncwrapper+0)+8*A_PtrSize), "Ptr", sfileasyncwrapper, "Ptr*", sfile) + + ; 4. Create LockScreen obj + VarSetCapacity(IIDLockScreenStatics, 16), VA_GUID(IIDLockScreenStatics := "{3EE9D3AD-B607-40AE-B426-7631D9821269}") + lockScreen := new HSTRING("Windows.System.UserProfile.LockScreen") + if (!DllCall("combase.dll\RoGetActivationFactory", "Ptr", lockScreen.str, "Ptr", &IIDLockScreenStatics, "Ptr*", instLockScreen)) { + ; Tell ls obj to set ls pic from sf obj + DllCall(NumGet(NumGet(instLockScreen+0)+8*A_PtrSize), "Ptr", instLockScreen, "Ptr", sfile, "Ptr*", Operation) + + sfileasyncinfo := ComObjQuery(Operation, IID_IAsyncInfo := "{00000036-0000-0000-C000-000000000046}") + while (!DllCall(NumGet(NumGet(sfileasyncinfo+0)+7*A_PtrSize), "Ptr", sfileasyncinfo, "UInt*", status) && !status) + Sleep 100 + ObjRelease(sfileasyncinfo) + + ObjRelease(Operation) + ObjRelease(instLockScreen) + } + + ObjRelease(sfile) + ObjRelease(sfileasyncwrapper) + } + ObjRelease(instStorageFile) + } +} + +class HSTRING { + static lpWindowsCreateString := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "combase.dll", "Ptr"), "AStr", "WindowsCreateString", "Ptr") + static lpWindowsDeleteString := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "combase.dll", "Ptr"), "AStr", "WindowsDeleteString", "Ptr") + + __New(sourceString, length := 0) { + this.str := !DllCall(HSTRING.lpWindowsCreateString, "WStr", sourceString, "UInt", length ? length : StrLen(sourceString), "Ptr*", string) ? string : 0 + } + + __Delete() { + DllCall(HSTRING.lpWindowsDeleteString, "Ptr", this.str) + } +} + +; From Lexikos' VA.ahk: Convert string to binary GUID structure. +VA_GUID(ByRef guid_out, guid_in="%guid_out%") { + if (guid_in == "%guid_out%") + guid_in := guid_out + if guid_in is integer + return guid_in + VarSetCapacity(guid_out, 16, 0) + DllCall("ole32\CLSIDFromString", "wstr", guid_in, "ptr", &guid_out) + return &guid_out +} \ No newline at end of file diff --git a/ShowNetworkNames.ahk b/ShowNetworkNames.ahk new file mode 100644 index 0000000..5702abb --- /dev/null +++ b/ShowNetworkNames.ahk @@ -0,0 +1,45 @@ +#NoEnv +VarSetCapacity(adapterGuid, 16), VarSetCapacity(adapterGuidStr, 140), adapters := GetAdaptersAddresses() + +; Thanks to Lexikos and HotKeyIt for correcting my attempts + +for INetwork in ComObjCreate("{DCB00C01-570F-4A9B-8D69-199FDBA5723B}").GetNetworks(1) { ; NLM_ENUM_NETWORK_CONNECTED ; NLM_ENUM_NETWORK_ALL := 3 + ; INetwork.SetCategory(1) ; NLM_NETWORK_CATEGORY_PRIVATE - uncommenting designates the connected network as "Private". 0 would set it as "Public". You need to be admin for this to have an effect + profileName := INetwork.GetName() + for k, v in INetwork.GetNetworkConnections() { + try if ((INetworkConnection := ComObjQuery(k, "{DCB00005-570F-4A9B-8D69-199FDBA5723B}"))) { + if (DllCall(NumGet(NumGet(INetworkConnection+0)+12*A_PtrSize), "Ptr", INetworkConnection, "Ptr", &adapterGuid) == 0) { ; ::GetAdapterId + if (DllCall("ole32\StringFromGUID2", "Ptr", &adapterGuid, "WStr", adapterGuidStr, "Int", 68)) { + adapterName := adapters[adapterGuidStr].Description + interfaceAlias := adapters[adapterGuidStr].FriendlyName + } + } + ObjRelease(INetworkConnection) + } + } + MsgBox % profileName . "`n" . adapterName . "`n" . interfaceAlias +} + +; By just me: https://autohotkey.com/boards/viewtopic.php?t=18768 +GetAdaptersAddresses() +{ + ; initial call to GetAdaptersAddresses to get the size needed + If (DllCall("iphlpapi.dll\GetAdaptersAddresses", "UInt", 2, "UInt", 0, "Ptr", 0, "Ptr", 0, "UIntP", Size) = 111) ; ERROR_BUFFER_OVERFLOW + If !(VarSetCapacity(Buf, Size, 0)) + Return "Memory allocation failed for IP_ADAPTER_ADDRESSES struct" + + ; second call to GetAdapters Addresses to get the actual data we want + If (DllCall("iphlpapi.dll\GetAdaptersAddresses", "UInt", 2, "UInt", 0, "Ptr", 0, "Ptr", &Buf, "UIntP", Size) != 0) ; NO_ERROR + Return "Call to GetAdaptersAddresses failed with error: " . A_LastError + + Addr := &Buf + Adapters := {} + While (Addr) { + AdapterName := StrGet(NumGet(Addr + 8, A_PtrSize, "Uptr"), "CP0") + Description := StrGet(NumGet(Addr + 8, A_PtrSize * 7, "UPtr"), "UTF-16") + FriendlyName := StrGet(NumGet(Addr + 8, A_PtrSize * 8, "UPtr"), "UTF-16") + Adapters[AdapterName] := {Description: Description, FriendlyName: FriendlyName} + Addr := NumGet(Addr + 8, "UPtr") ; *Next + } + Return Adapters +} \ No newline at end of file diff --git a/ShowWindows10TrayClock.ahk b/ShowWindows10TrayClock.ahk new file mode 100644 index 0000000..0904510 --- /dev/null +++ b/ShowWindows10TrayClock.ahk @@ -0,0 +1,17 @@ +#NoEnv + +ControlGet, hClock, Hwnd,, TrayClockWClass1, ahk_class Shell_TrayWnd ; https://autohotkey.com/board/topic/70770-win7-taskbar-clock-toggle/ +if (hClock) { + VarSetCapacity(IID_IAccessible, 16), DllCall("ole32\CLSIDFromString", "WStr", "{618736e0-3c3d-11cf-810c-00aa00389b71}", "Ptr", &IID_IAccessible) + if (DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hClock, "UInt", OBJID_CLIENT := 0xFFFFFFFC, "Ptr", &IID_IAccessible, "Ptr*", accTrayClock)) + return + VarSetCapacity(variant, A_PtrSize == 8 ? 24 : 16, 0), NumPut(VT_I4 := 3, variant,, "UShort") + if (A_PtrSize == 4) ; Thanks Eidola: https://autohotkey.com/boards/viewtopic.php?p=111355#p111355 + DllCall(NumGet(NumGet(accTrayClock+0)+25*A_PtrSize), "Ptr", accTrayClock, "Int64", NumGet(variant, 0, "Int64"), Int64, NumGet(variant, 8, "Int64")) ; IAccessible::DoDefaultAction + else + DllCall(NumGet(NumGet(accTrayClock+0)+25*A_PtrSize), "Ptr", accTrayClock, "Ptr", &variant) ; IAccessible::DoDefaultAction + ObjRelease(accTrayClock) +} + +/* ControlGet, hClock, Hwnd,, TrayClockWClass1, ahk_class Shell_TrayWnd ; https://autohotkey.com/board/topic/70770-win7-taskbar-clock-toggle/ +PostMessage, 0x466, 1, 0,, ahk_id %hClock% */ \ No newline at end of file diff --git a/ThinkPadScripts/EnableTrackPointAndButtonsOnlyWhenFnIsHeld.ahk b/ThinkPadScripts/EnableTrackPointAndButtonsOnlyWhenFnIsHeld.ahk new file mode 100644 index 0000000..c26c1ac --- /dev/null +++ b/ThinkPadScripts/EnableTrackPointAndButtonsOnlyWhenFnIsHeld.ahk @@ -0,0 +1,30 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +AutoTrim, Off +ListLines, Off +SetBatchLines, -1 +#KeyHistory 0 + +SP_DisableState := 0x10000171 +SynAPI := ComObjCreate("SynCtrl.SynAPICtrl") +SynAPI.Initialize +SynDev := ComObjCreate("SynCtrl.SynDeviceCtrl") +SynDev.Select(SynAPI.FindDevice(SE_ConnectionAny := 0, SE_DeviceIBMCompatibleStick := 4, 0)) +OnExit("AtExit") +SynDev.SetLongProperty(SP_DisableState, True) ; force TrackPoint to be disabled at startup of script +return + +SC163:: +SynDev.SetLongProperty(SP_DisableState, False) ; enable device when Fn pressed +return + +SC163 up:: ; Replace 159 with your key's value. +SynDev.SetLongProperty(SP_DisableState, True) ; disable device when Fn key released +return + +Esc::ExitApp + +AtExit() { + global SynDev, SP_DisableState + SynDev.SetLongProperty(SP_DisableState, False) ; re-enable TP at exit of script +} \ No newline at end of file diff --git a/ThinkPadScripts/LenovoBatterySetRegisterThresholds.ahk b/ThinkPadScripts/LenovoBatterySetRegisterThresholds.ahk new file mode 100644 index 0000000..6df7b9e --- /dev/null +++ b/ThinkPadScripts/LenovoBatterySetRegisterThresholds.ahk @@ -0,0 +1,93 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +AutoTrim, Off +ListLines, Off +SetBatchLines, -1 +SetFormat, FloatFast, 0.6 +SetFormat, IntegerFast, D +#KeyHistory 0 + +; adapted from heresy's lib +Service_Start(ServiceName) +{ + if (!A_IsAdmin) + return true + result := false + + SCM_HANDLE := DllCall("advapi32\OpenSCManager", "Ptr", 0, "Ptr", 0, "UInt", 0x1, "Ptr") + if (SCM_HANDLE) { + if (SC_HANDLE := DllCall("advapi32\OpenService", "Ptr", SCM_HANDLE, "Str", ServiceName, "UInt", 0x10, "Ptr")) { + result := DllCall("advapi32\StartService", "Ptr", SC_HANDLE , "UInt", 0, "Ptr", 0) + DllCall("advapi32\CloseServiceHandle", "Ptr", SC_HANDLE) + } + DllCall("advapi32\CloseServiceHandle", "Ptr", SCM_HANDLE) + if (!SC_HANDLE) ; Service not found + ErrorLevel := -4 + } + if (result) + ErrorLevel := 0 + return result +} + +; all credits to XYUU +WatchLenovoBatteryKey_SetRegisterThresholds(bId, start, stop) +{ + ; yes, this is ugly, but w/e - I'm not a programmer :-) + start := ((start >= 1 && start <= 100)) ? start - 1 : (start == 0 ? start : -1) + stop := ((stop >= 0 && start <= 100)) ? (stop == 100 ? 0x00 : stop) : -1 + + if (start != -1 || stop != -1) + { + INVALID_HANDLE_VALUE := -1 + GENERIC_READ := 0x80000000 ;, GENERIC_WRITE := 0x40000000 + FILE_SHARE_READ := 0x00000001 ;, FILE_SHARE_WRITE := 0x00000002 + + Service_Start("IBMPMDRV") ; make sure the IBM Power Management driver is running + IBMPmDrv := DllCall("CreateFile", "Str", "\\.\IBMPmDrv", "UInt", GENERIC_READ, "UInt", FILE_SHARE_READ, "Ptr", 0, "UInt", OPEN_EXISTING := 3, "UInt", 0, "Ptr", 0, "Ptr") + if (IBMPmDrv && IBMPmDrv != INVALID_HANDLE_VALUE) + { + currStartValue := currStopValue := 0x00 + + ; get the current threshold values + for i, ioctl in [GET_BATTERY_THRESH_START := 0x22262C, GET_BATTERY_THRESH_STOP := 0x222634] + { + VarSetCapacity(GET_BATTERY_THRESH_IN, reqBufSzGetIn := 4, 0), VarSetCapacity(GET_BATTERY_THRESH_OUT, reqBufSzGetOut := 4, 0) + NumPut(bId, GET_BATTERY_THRESH_IN,, "UChar") + if ((DllCall("DeviceIoControl", "Ptr", IBMPmDrv, "UInt", ioctl, "Ptr", &GET_BATTERY_THRESH_IN, "UInt", reqBufSzGetIn, "Ptr", &GET_BATTERY_THRESH_OUT, "UInt", reqBufSzGetOut, "UInt*", actualOutSz, "Ptr", 0)) && actualOutSz == reqBufSzGetOut) { + if (ioctl == GET_BATTERY_THRESH_START) + currStartValue := NumGet(GET_BATTERY_THRESH_OUT,, "UChar") + else if (ioctl == GET_BATTERY_THRESH_STOP) + currStopValue := NumGet(GET_BATTERY_THRESH_OUT,, "UChar") + } + } + + ; set the new thresholds if they're different + for i, ioctl in [SET_BATTERY_THRESH_START := 0x222630, SET_BATTERY_THRESH_STOP := 0x222638] + { + val := -1 + if (ioctl == SET_BATTERY_THRESH_START) + { + if (start != currStartValue) + val := start + } + else if (ioctl == SET_BATTERY_THRESH_STOP) + { + if (stop != currStopValue) + val := stop + } + + if (val > -1) + { + VarSetCapacity(SET_BATTERY_THRESH_IN, reqBufSz := 4, 0) + NumPut(val, SET_BATTERY_THRESH_IN,, "UChar"), NumPut(bId, SET_BATTERY_THRESH_IN, 1, "UChar") + DllCall("DeviceIoControl", "Ptr", IBMPmDrv, "UInt", ioctl, "Ptr", &SET_BATTERY_THRESH_IN, "UInt", reqBufSz, "Ptr", 0, "UInt", 0, "Ptr", 0, "Ptr", 0) + } + } + + DllCall("CloseHandle", "Ptr", IBMPmDrv) + } + } +} + +MsgBox This will set your battery charging thresholds to start at 20`% and to stop at 90`%. Exit now from the tray menu if you do not want this. + +WatchLenovoBatteryKey_SetRegisterThresholds(0x01, 20, 90) ; DEFAULT_BATTERY_ID == 0x01, see https://github.com/teleshoes/tpacpi-bat/blob/master/battery_asl#L200 diff --git a/ThinkPadScripts/README.md b/ThinkPadScripts/README.md new file mode 100644 index 0000000..c639087 --- /dev/null +++ b/ThinkPadScripts/README.md @@ -0,0 +1,24 @@ +Scripts specific to my X230 laptop. + +EnableTrackPointAndButtonsOnlyWhenFnIsHeld - does what it says. You can press Escape to exit the script at any time. Credits: + +* The people in this thread https://autohotkey.com/board/topic/65849-controlling-synaptics-touchpad-using-com-api/ + +* Synaptics for their SDK - specifically the Disabler program + +LenovoBatterySetRegisterThresholds - asks the IBM power management driver directly to set the battery thresholds, removing the only reason I might have had to keep Lenovo's UWP abomination around. +The method used comes from RE work by XYUU. See his blog post [here](https://zhuanlan.zhihu.com/p/20706403) and his application [here](https://github.com/XYUU/BatteryUtils). + +Things to be aware of: + +* When you run it, it will set the thresholds right away. You should change them before running the script for the first time. + +* This script just asks the IBM driver to set the thresholds and then exits. It is not persistent. And for that matter, the threshold setting changes it makes might not always be remembered by the EC. I run this on startup. + +* If you don't like the script, just have it set your thresholds back to the original values (0, 100) and delete it - it leaves nothing else lying around + +* Lenovo software itself might reset the thresholds. I uninstalled Lenovo Settings, the ThinkPad Settings Dependency package and Lenovo System Interface Foundation + +* If the script is run elevated (not a requirement), it will try to make sure the IBM power management driver is started + +I do have an AutoHotkey script that makes the microphone LED blink when the CapsLock key is pressed, but [this](https://gitlab.com/valinet/thinkpad-leds-control) is a better program for it. \ No newline at end of file diff --git a/ToggleWindows10TabletMode.ahk b/ToggleWindows10TabletMode.ahk new file mode 100644 index 0000000..7c03b78 --- /dev/null +++ b/ToggleWindows10TabletMode.ahk @@ -0,0 +1,26 @@ +#NoEnv +SetBatchLines -1 +ListLines Off +#NoTrayIcon + +TABLETMODESTATE_DESKTOPMODE := 0x0 +TABLETMODESTATE_TABLETMODE := 0x1 + +TabletModeController_GetMode(TabletModeController, ByRef mode) { + return DllCall(NumGet(NumGet(TabletModeController+0),3*A_PtrSize), "Ptr", TabletModeController, "UInt*", mode) +} + +TabletModeController_SetMode(TabletModeController, _TABLETMODESTATE, _TMCTRIGGER := 4) { + return DllCall(NumGet(NumGet(TabletModeController+0),4*A_PtrSize), "Ptr", TabletModeController, "UInt", _TABLETMODESTATE, "UInt", _TMCTRIGGER) +} + + MsgBox This will put Windows 10 into Tablet Mode. Exit now from the tray menu if you do not want this. (You can go back from the Windows 10 settings or by running this script again.) + +ImmersiveShell := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{00000000-0000-0000-C000-000000000046}") +TabletModeController := ComObjQuery(ImmersiveShell, "{4fda780a-acd2-41f7-b4f2-ebe674c9bf2a}", "{4fda780a-acd2-41f7-b4f2-ebe674c9bf2a}") + +if (TabletModeController_GetMode(TabletModeController, mode) == 0) + TabletModeController_SetMode(TabletModeController, mode == TABLETMODESTATE_DESKTOPMODE ? TABLETMODESTATE_TABLETMODE : TABLETMODESTATE_DESKTOPMODE) + +ObjRelease(TabletModeController), TabletModeController := 0 +ObjRelease(ImmersiveShell), ImmersiveShell := 0 ; Can be freed after TabletModeController is created, instead \ No newline at end of file diff --git a/ToggleWindows10TabletOSK.ahk b/ToggleWindows10TabletOSK.ahk new file mode 100644 index 0000000..3141188 --- /dev/null +++ b/ToggleWindows10TabletOSK.ahk @@ -0,0 +1,12 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +#NoTrayIcon + +; Credits: torvin - https://stackoverflow.com/a/40921638 + +try { + ITipInvocation := ComObjCreate("{4ce576fa-83dc-4F88-951c-9d0782b4e376}", "{37c994e7-432b-4834-a2f7-dce1f13b834b}") + DllCall(NumGet(NumGet(ITipInvocation+0)+3*A_PtrSize), "Ptr", ITipInvocation, "Ptr", DllCall("GetDesktopWindow", "Ptr")) + ObjRelease(ITipInvocation) +} catch { + Run %A_ProgramFiles%\Common Files\microsoft shared\ink\TabTip.exe, %A_ProgramFiles%\Common Files\microsoft shared\ink\, UseErrorLevel +} \ No newline at end of file diff --git a/WinHTTPFileDownloader/README.md b/WinHTTPFileDownloader/README.md new file mode 100644 index 0000000..93398d6 --- /dev/null +++ b/WinHTTPFileDownloader/README.md @@ -0,0 +1,9 @@ +![WinHTTPFileDownloader](https://i.imgur.com/HTqb6b6.png) + +A very messy script that downloads a segment of waik_supplement_en-us.iso, written for https://autohotkey.com/boards/viewtopic.php?f=5&t=17370 + +There is no buffering mechanism to speak of, it downloads a hardcoded segment from a file determined from a hardcoded URL path to a hardcoded filename. + +just me's [Class_TaskDialog](https://autohotkey.com/boards/viewtopic.php?f=6&t=5711) is needed. + +For something that actually works, you might consider https://github.com/potmdehex/WinInet-Downloader instead. \ No newline at end of file diff --git a/WinHTTPFileDownloader/WinHTTPFileDownloader.ahk b/WinHTTPFileDownloader/WinHTTPFileDownloader.ahk new file mode 100644 index 0000000..d004b35 --- /dev/null +++ b/WinHTTPFileDownloader/WinHTTPFileDownloader.ahk @@ -0,0 +1,352 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +SetWorkingDir D:\ ; My RAMDisk, you'll probably want AHK's default of %A_ScriptDir% +SetBatchLines -1 +ListLines Off + +#Include Class_TaskDialog.ahk + +if (hModule := WinHttp_Init()) ; load winhttp library. Will fail if not running on a Unicode build of AHK + hSession := WinHttp_Open("WinHTTP Example/1.0", "WINHTTP_ACCESS_TYPE_NO_PROXY", "WINHTTP_NO_PROXY_NAME", "WINHTTP_NO_PROXY_BYPASS") ; Open WinHttp session - set User Agent and proxy settings + +if (hSession) + hConnect := WinHttp_Connect(hSession, "download.microsoft.com", "INTERNET_DEFAULT_HTTP_PORT") ; Not relevant here, but it's worth noting the same connection can be used for multiple requests from the same site to speed up things + +if (hConnect) + hRequest := WinHttp_OpenRequest(hConnect,, "/download/0/4/C/04C805CC-4C04-4D76-BE80-7D67B951CF73/waik_supplement_en-us.iso") ; the path to access from the domain above. WinHttpCrackUrl() (which is not wrapped here) can break down a full URL + +/* +if (hSession) + hConnect := WinHttp_Connect(hSession, "127.0.0.1", 8080) + +if (hConnect) + hRequest := WinHttp_OpenRequest(hConnect,, "/waik_supplement_en-us.iso") +*/ + +; Adding resuming support is, I believe, bytes=%bytesDownloaded%-450673718 and opening the already-existing file in append mode +if (hRequest) + bResults := WinHttp_SendRequest(hRequest, "Range: bytes=336336896-450673718") ; Add header to download the specified range. I *think* adding additional headers is a matter of delimiting them in the same string with `r`n + +if (bResults) + bResults := DllCall("winhttp\WinHttpReceiveResponse", "Ptr", hRequest, "Ptr", NULL) + +if (bResults) +{ + ; Get response headers + + ; Determine size of buffer to store headers in + if (!WinHttp_QueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF := 22, WINHTTP_HEADER_NAME_BY_INDEX := 0, 0, dwSize := 0, WINHTTP_NO_HEADER_INDEX := 0)) + { + if (A_LastError == 0x7A) ; ERROR_INSUFFICIENT_BUFFER + { + VarSetCapacity(outBuffer, dwSize + 2) ; allocate space needed for the actual headers + if (WinHttp_QueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, &outBuffer, dwSize, WINHTTP_NO_HEADER_INDEX)) + { + ; call WinHttp_QueryHeaders again to actually get the response headers now that there's a buffer with enough space to store the result + responseHeaders := StrGet(&outBuffer, "UTF-16") + + ; I'm sure there's a quicker way than this somewhere to get just the Content-Length... + y := SubStr(responseHeaders, InStr(responseHeaders, "Content-Length: ")) + if (y) + Content_Length := StrSplit(SubStr(y, 1, InStr(y, "`r") - 1), ":", " ")[2] + + ; If the file already exists, you could compare the size of that file with the Content_Length above to see if the file is already downloaded in its entirety + } + } + } +} + +if (bResults) +{ + fileName := "7x86winpe.wim" ; save file with this name + + TD := New TaskDialog(FormatTitle("0.00 MB"),, "Downloading " . filename, ["Cancel"]) + TD.SetProgressBar("NONMARQUEE") + TD.SetAlwaysOnTop() + TD.SetCallbackFunc("TaskDialogCustomCallback") + TD.AllowCancel() + + TD.Show() ; blocks, hence the SetTimer awkwardness in the callback +} + +if (!bResults) + MsgBox Error %A_LastError% has occurred + +WinHttp_CloseHandle(hRequest) +WinHttp_CloseHandle(hConnect) +WinHttp_CloseHandle(hSession) + +WinHttp_Deinit(hModule) +ExitApp + +TaskDialogCustomCallback(H, N, W, L, D) +{ + global shouldCancel + if (N == 0) ; TDN_CREATED + { + SetTimer, StartDownloading, -5 + } + else if (N == 2) ; TDN_BUTTON_CLICKED + { + shouldCancel := true + } + return 0 +} + +StartDownloading() +{ + global fileName, hRequest, TD, Content_Length, shouldCancel + hFile := FileOpen(fileName, "w") ; open the file named in the first argument for writing + Loop + { + if (shouldCancel) + break + ; A buffering/caching mechanism, like HttpRequest has, instead of instantly writing the recieved to the disk would be nice + if (!WinHttp_QueryDataAvailable(hRequest, dwSize)) + { + TD.TDM_SET_PROGRESS_BAR_STATE("ERROR") + TD.TDM_UPDATE_ELEMENT_TEXT("MAIN", "Error " . A_LastError . " in WinHttpQueryDataAvailable") + shouldCancel := true + break + } + if (VarSetCapacity(pszOutBuffer, dwSize + 1, 0) < dwSize + 1) + { + OutputDebug Out of memory + ExitApp + } + if (!WinHttp_ReadData(hRequest, &pszOutBuffer, dwSize, dwDownloaded)) + { + TD.TDM_SET_PROGRESS_BAR_STATE("ERROR") + TD.TDM_UPDATE_ELEMENT_TEXT("MAIN", "Error " . A_LastError . " in WinHttpReadData") + ; shouldCancel := true + } + else + { + hFile.RawWrite(pszOutBuffer, dwDownloaded) ; write the downloaded bytes to the file + + totalDownloaded += dwDownloaded + pct := Ceil((totalDownloaded * 100) / Content_Length) + if (pct != lastPct || pct >= 100) { ; Just for that last update + TD.TDM_SET_PROGRESS_BAR_POS(pct), lastPct := pct + TD.TDM_UPDATE_ELEMENT_TEXT("MAIN", FormatTitle(FormatBytes(totalDownloaded))) ; Move outside of the if block for more frequent updates at the cost of more CPU usage + } + } + if (dwSize <= 0) + break + } + if (!shouldCancel) + SetTimer, CloseTD, -3000 + hFile.Close() +} + +FormatTitle(bytes) +{ + global Content_Length + return "Downloaded " . bytes . (Content_Length ? " of " . FormatBytes(Content_Length) : "") +} + +; By SKAN +FormatBytes(bytes) { + VarSetCapacity(pszBuf, 32) + return DllCall("Shlwapi\StrFormatByteSizeW", "Int64", bytes, "Ptr", &pszBuf, "UInt", 32, "WStr") +} + +CloseTD() +{ + global TD + TD.TDM_CLICK_BUTTON(8) ; Manually trigger click of the cancel button +} + +; --- Incomplete, bad wrapper library follows + +WinHttp_Init() +{ + if (!A_IsUnicode) + return 0 + return DllCall("LoadLibrary", "Str", "winhttp.dll", "Ptr") +} + +WinHttp_Deinit(hModule) +{ + DllCall("FreeLibrary", "Ptr", hModule) +} + +WinHttp_CloseHandle(hInternet) +{ + if (hInternet) + DllCall("winhttp\WinHttpCloseHandle", "Ptr", hInternet) +} + +WinHttp_Open(userAgent, proxyType := "WINHTTP_ACCESS_TYPE_DEFAULT_PROXY", proxyName := "", proxyBypass := "", flags := "") +{ + if (!userAgent) + return 0 + + if proxyType not in WINHTTP_ACCESS_TYPE_NO_PROXY,WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_ACCESS_TYPE_NAMED_PROXY + return 0 + + if (!proxyName || proxyName == "WINHTTP_NO_PROXY_NAME") + { + pnType := "Ptr" + proxyName := _WinHttp_DWordFromWHConstant("WINHTTP_NO_PROXY_NAME") + } + else + { + pnType := "WStr" + } + + if (!proxyBypass || proxyBypass == "WINHTTP_NO_PROXY_BYPASS") + { + pbType := "Ptr" + proxyBypass := _WinHttp_DWordFromWHConstant("WINHTTP_NO_PROXY_BYPASS") + } + else + { + pbType := "WStr" + } + + if (flags && flags != "WINHTTP_FLAG_ASYNC") + return 0 + else + flags := flags ? _WinHttp_DWordFromWHConstant("WINHTTP_FLAG_ASYNC") : 0 + + return DllCall("winhttp\WinHttpOpen", "WStr", userAgent + ,"UInt", _WinHttp_DWordFromWHConstant(proxyType) + ,pnType, proxyName + ,pbType, proxyBypass + ,"UInt", flags + ,"Ptr") +} + +WinHttp_Connect(hSession, ServerName, ServerPort := "INTERNET_DEFAULT_PORT") +{ + if (!hSession || !ServerName) + return 0 + + if ServerPort is not integer + { + if ServerPort not in INTERNET_DEFAULT_PORT,INTERNET_DEFAULT_HTTP_PORT,INTERNET_DEFAULT_HTTPS_PORT + return 0 + ServerPort := _WinHttp_DWordFromWHConstant(ServerPort) + } + + return DllCall("winhttp\WinHttpConnect", "Ptr", hSession + ,"WStr", ServerName + ,"UInt", ServerPort + ,"UInt", 0 + ,"Ptr") +} + +WinHttp_OpenRequest(hConnect, verb := "GET", objectName := "", httpVersion := "", referrer := "WINHTTP_NO_REFERER", acceptTypes := "WINHTTP_DEFAULT_ACCEPT_TYPES", flags := "") +{ + if (!hConnect || !objectName) ; don't ask + return 0 + + if (!referrer || referrer == "WINHTTP_NO_REFERER") + referrer := _WinHttp_DWordFromWHConstant("WINHTTP_NO_REFERER") + + if (!acceptTypes || acceptTypes == "WINHTTP_DEFAULT_ACCEPT_TYPES") + acceptTypes := _WinHttp_DWordFromWHConstant("WINHTTP_DEFAULT_ACCEPT_TYPES") + + if (flags) + { + if (!InStr(flags, "|")) + flags := flags . "|" + flagsSplit := StrSplit(flags, "|", " `r`n`t") + actualFlags := 0 + Loop % flagsSplit.MaxIndex() + { + if (flagsSplit[A_Index]) + { + if flagsSplit[A_Index] not in WINHTTP_FLAG_SECURE,WINHTTP_FLAG_ESCAPE_PERCENT + ,WINHTTP_FLAG_NULL_CODEPAGE,WINHTTP_FLAG_BYPASS_PROXY_CACHE + ,WINHTTP_FLAG_REFRESH,WINHTTP_FLAG_ESCAPE_DISABLE,WINHTTP_FLAG_ESCAPE_DISABLE_QUERY + { + return 0 + } + else + { + actualFlags := actualFlags | _WinHttp_DWordFromWHConstant(flagsSplit[A_Index]) + } + } + } + } + else + { + actualFlags := 0 + } + + return DllCall("winhttp\WinHttpOpenRequest", "Ptr", hConnect + ,"WStr", verb + ,"WStr", objectName + ,httpVersion ? "WStr" : "Ptr", httpVersion ? httpVersion : 0 + ,referrer ? "WStr" : "Ptr", referrer + ,acceptTypes ? "WStr" : "Ptr", acceptTypes + ,"UInt", actualFlags + ,"Ptr") +} + +WinHttp_SendRequest(hRequest, headers := "WINHTTP_NO_ADDITIONAL_HEADERS", headersLength := -1 + , optionalData := "WINHTTP_NO_REQUEST_DATA", optionalDataLength := 0, totalLength := 0 + , context := 0) +{ + if (!headers || headers == "WINHTTP_NO_ADDITIONAL_HEADERS") + headers := _WinHttp_DWordFromWHConstant("WINHTTP_NO_ADDITIONAL_HEADERS") + + if (!optionalData || optionalData == "WINHTTP_NO_REQUEST_DATA") + optionalData := _WinHttp_DWordFromWHConstant("WINHTTP_NO_REQUEST_DATA") + + return DllCall("winhttp\WinHttpSendRequest", "Ptr", hRequest + ,headers ? "WStr" : "Ptr", headers + ,"UInt", headers ? headersLength : 0 + ,optionalData ? "WStr" : "Ptr", optionalData + ,"UInt", optionalDataLength + ,"UInt", totalLength + ,"Ptr", context) +} + +WinHttp_QueryDataAvailable(hRequest, ByRef dwNumberOfBytesAvailable) +{ + if (!IsByRef(dwNumberOfBytesAvailable)) + return false + return DllCall("winhttp\WinHttpQueryDataAvailable", "Ptr", hRequest, "UInt*", dwNumberOfBytesAvailable) +} + +WinHttp_ReadData(hRequest, pointerToBuffer, bufferSize, ByRef dwDownloaded) +{ + return DllCall("winhttp\WinHttpReadData", "Ptr", hRequest, "Ptr", pointerToBuffer, "UInt", bufferSize, "UInt*", dwDownloaded) +} + +WinHttp_QueryHeaders(hRequest, infoLevel, name, ptrBuffer, ByRef bufferSize, headerIndex) +{ + if (!IsByRef(bufferSize)) + return false + ; Sorry, too many flags here for me to, uhm, neatly wrap + return DllCall("winhttp\WinHttpQueryHeaders", "Ptr", hRequest, "UInt", infoLevel, "Ptr", name, "Ptr", ptrBuffer, "UInt*", bufferSize, "Ptr", headerIndex) +} + +_WinHttp_DWordFromWHConstant(constant) +{ + static something := { "WINHTTP_NO_PROXY_NAME" : 0 + ,"WINHTTP_NO_PROXY_BYPASS" : 0 + ,"WINHTTP_ACCESS_TYPE_DEFAULT_PROXY" : 0 + ,"WINHTTP_ACCESS_TYPE_NO_PROXY" : 1 + ,"WINHTTP_ACCESS_TYPE_NAMED_PROXY" : 3 + ,"WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY" : 4 + ,"INTERNET_DEFAULT_PORT" : 0 + ,"INTERNET_DEFAULT_HTTP_PORT" : 80 + ,"INTERNET_DEFAULT_HTTPS_PORT" : 443 + ,"WINHTTP_NO_REFERER" : 0 + ,"WINHTTP_DEFAULT_ACCEPT_TYPES" : 0 + ,"WINHTTP_NO_ADDITIONAL_HEADERS" : 0 + ,"WINHTTP_NO_REQUEST_DATA" : 0 + ,"WINHTTP_FLAG_ASYNC" : 0x10000000 + ,"WINHTTP_FLAG_SECURE" : 0x00800000 + ,"WINHTTP_FLAG_ESCAPE_PERCENT" : 0x00000004 + ,"WINHTTP_FLAG_NULL_CODEPAGE" : 0x00000008 + ,"WINHTTP_FLAG_BYPASS_PROXY_CACHE" : 0x00000100 + ,"WINHTTP_FLAG_REFRESH" : 0x00000100 + ,"WINHTTP_FLAG_ESCAPE_DISABLE" : 0x00000040 + ,"WINHTTP_FLAG_ESCAPE_DISABLE_QUERY" : 0x00000080} + + return something[constant] +} \ No newline at end of file diff --git a/XPGetLeftAndRightChannelsVolume.ahk b/XPGetLeftAndRightChannelsVolume.ahk new file mode 100644 index 0000000..18fbac5 --- /dev/null +++ b/XPGetLeftAndRightChannelsVolume.ahk @@ -0,0 +1,74 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +WaveOutIDOfPreferredDevice := mixerID := 0 +if (DllCall("winmm\waveOutMessage", "Ptr", WAVE_MAPPER := -1, "UInt", DRVM_MAPPER_PREFERRED_GET := 0x2015, "UInt*", WaveOutIDOfPreferredDevice, "UInt*", Status, "UInt") == 0 + && DllCall("winmm\mixerGetID", "Ptr", WaveOutIDOfPreferredDevice, "UInt*", mixerID, "UInt", MIXER_OBJECTF_WAVEOUT := 0x10000000, "UInt") == 0 + && FindDevIDs(mixerID, volID, finalDestination)) { + if (DllCall("winmm\mixerOpen", "Ptr*", hmx, "UInt", mixerID, "UInt", 0, "UInt", 0, "UInt", MIXER_OBJECTF_WAVEOUT, "UInt") == 0) { + VarSetcapacity(mxl, 280, 0) + NumPut(280, mxl,, "UInt") + NumPut(finalDestination, mxl, 4, "UInt") + if (DllCall("winmm\mixerGetLineInfo", "Ptr", hmx, "Ptr", &mxl, "UInt", 0, "UInt") == 0) { + channels := NumGet(mxl, 28, "UInt") + VarSetcapacity(mcd, 24, 0) + VarSetcapacity(m, 4 * channels, 0) + NumPut(24, mcd,, "UInt") + NumPut(volID, mcd, 4, "UInt") + NumPut(channels, mcd, 8, "UInt") + NumPut(4, mcd, 16, "UInt") + NumPut(&m, mcd, 20, "Ptr") + if (DllCall("winmm\mixerGetControlDetailsW", "Ptr", hmx, "Ptr", &mcd, "UInt", 0, "UInt") == 0) { + Loop % channels + MsgBox % Round((NumGet(m, 4 * (A_Index - 1), "UInt") / 0xFFFF) * 100) + } + } + DllCall("winmm\mixerClose", "Ptr", hmx) + } +} + +FindDevIDs(mixerID, ByRef volID, ByRef finalDestination) +{ + VarSetcapacity(mxcapsw, (cbmxcaps := 80)) + ret := False + + if (DllCall("winmm\mixerGetDevCapsW", "UInt", mixerID, "Ptr", &mxcapsw, "UInt", cbmxcaps) == 0) { + if ((destinations := NumGet(mxcapsw, cbmxcaps - 4, "UInt")) > 0) { + VarSetcapacity(mxl, (cbmxl := 280)) + dest := 0 + while (!ret && dest < destinations) { + NumPut(cbmxl, mxl,, "UInt") + NumPut(dest, mxl, 4, "UInt") + if (DllCall("winmm\mixerGetLineInfoW", "Ptr", mixerID, "Ptr", &mxl, "UInt", 0, "UInt") == 0) { + componentType := NumGet(mxl, 24, "UInt") + if (componentType == 4 || componentType == 5 || componentType == 4104) { ; speakers, headphones & wave out + if ((controls := NumGet(mxl, 36, "UInt")) && !ret) { ; controls present + finalDestination := dest + control := 0 + cbmc := 228 + VarSetcapacity(mc, controls * cbmc) + VarSetcapacity(mxlc, (cbmxl := 24), 0) + NumPut(cbmxl, mxlc,, "UInt") + NumPut(NumGet(mxl, 12, "UInt"), mxlc, 4, "UInt") + NumPut(controls, mxlc, 12, "UInt") + NumPut(cbmc, mxlc, 16, "UInt") + NumPut(&mc, mxlc, 20, "Ptr") + + if (DllCall("winmm\mixerGetLineControlsW", "UInt", mixerID, "Ptr", &mxlc, "UInt", 0, "UInt") == 0) { + while (!ret && control < controls) { + if (NumGet(mc, 8 * control, "UInt") == 1342373889) { + ret := True + volID := NumGet(mc, 4 * control, "UInt") + } + control += 1 + } + } + } + } + } + dest += 1 + } + } + } + + return ret +} \ No newline at end of file diff --git a/XPSetLeftAndRightChannelsVolume.ahk b/XPSetLeftAndRightChannelsVolume.ahk new file mode 100644 index 0000000..cbc2b7d --- /dev/null +++ b/XPSetLeftAndRightChannelsVolume.ahk @@ -0,0 +1,106 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +Up::ShiftChannelVolume(1, 2, False) +Down::ShiftChannelVolume(1, -2, False) +Left::ShiftChannelVolume(0, -2, False) +Right::ShiftChannelVolume(0, 2, False) + +ShiftChannelVolume(channel, adj, jump) { + static mixerID, volID, finalDestination, Minimum, Maximum := -1, Steps, MIXER_OBJECTF_WAVEOUT := 0x10000000, mxl, mcd + + if (channel < 0) + return + + if (Maximum == -1) { + if (!(DllCall("winmm\waveOutMessage", "Ptr", WAVE_MAPPER := -1, "UInt", DRVM_MAPPER_PREFERRED_GET := 0x2015, "UInt*", WaveOutIDOfPreferredDevice, "UInt*", Status, "UInt") == 0 + && DllCall("winmm\mixerGetID", "Ptr", WaveOutIDOfPreferredDevice, "UInt*", mixerID, "UInt", MIXER_OBJECTF_WAVEOUT, "UInt") == 0 + && FindDevIDs(mixerID, volID, finalDestination, Minimum, Maximum, Steps))) { + Maximum := -1 + return + } + VarSetcapacity(mxl, 280) + VarSetcapacity(mcd, 24) + } + DllCall("ntdll\RtlZeroMemory", "Ptr", &mxl, "Ptr", 280) + NumPut(280, mxl,, "UInt"), NumPut(finalDestination, mxl, 4, "UInt") + + adj := CLAMP(adj, jump ? 0 : -100, 100) + + if (DllCall("winmm\mixerOpen", "Ptr*", hmx, "UInt", mixerID, "UInt", 0, "UInt", 0, "UInt", MIXER_OBJECTF_WAVEOUT, "UInt") == 0) { + if (DllCall("winmm\mixerGetLineInfo", "Ptr", hmx, "Ptr", &mxl, "UInt", 0, "UInt") == 0) { + channels := NumGet(mxl, 28, "UInt") + if (channel < channels) { + DllCall("ntdll\RtlZeroMemory", "Ptr", &mcd, "Ptr", 24) + VarSetcapacity(m, 4 * channels, 0) + NumPut(24, mcd,, "UInt") + NumPut(volID, mcd, 4, "UInt") + NumPut(channels, mcd, 8, "UInt") + NumPut(4, mcd, 16, "UInt") + NumPut(&m, mcd, 20, "Ptr") + + if (DllCall("winmm\mixerGetControlDetailsW", "Ptr", hmx, "Ptr", &mcd, "UInt", 0, "UInt") == 0) { + curVolume := Round((NumGet(m, 4 * channel, "UInt") / Maximum) * 100) + newVol := jump ? adj : CLAMP(curVolume + adj, 0, 100) + if (curVolume != newVol) { + NumPut((Maximum - Minimum) * (newVol / 100.0), m, 4 * channel, "UInt") ; stolen from the AutoHotkey source + DllCall("winmm\mixerSetControlDetails", "Ptr", hmx, "Ptr", &mcd, "UInt", 0, "UInt") + } + } + } + } + DllCall("winmm\mixerClose", "Ptr", hmx) + } +} + +FindDevIDs(mixerID, ByRef volID, ByRef finalDestination, ByRef Minimum, ByRef Maximum, ByRef Steps) +{ + VarSetcapacity(mxcapsw, (cbmxcaps := 80)) + + if (DllCall("winmm\mixerGetDevCapsW", "UInt", mixerID, "Ptr", &mxcapsw, "UInt", cbmxcaps) == 0) { + if ((destinations := NumGet(mxcapsw, cbmxcaps - 4, "UInt")) > 0) { + VarSetcapacity(mxl, (cbmxl := 280)) + NumPut(cbmxl, mxl,, "UInt") + cbmc := 228 + cbmxlc := 24 + Loop %destinations% { + dest := A_Index - 1 + NumPut(dest, mxl, 4, "UInt") + if (DllCall("winmm\mixerGetLineInfoW", "Ptr", mixerID, "Ptr", &mxl, "UInt", 0, "UInt") == 0) { + componentType := NumGet(mxl, 24, "UInt") + if (componentType == 4 || componentType == 5 || componentType == 4104) { ; speakers, headphones & wave out + if ((controls := NumGet(mxl, 36, "UInt"))) { ; controls present + finalDestination := dest + VarSetcapacity(mc, controls * cbmc) + VarSetcapacity(mxlc, cbmxlc, 0) + NumPut(cbmxlc, mxlc,, "UInt") + NumPut(NumGet(mxl, 12, "UInt"), mxlc, 4, "UInt") + NumPut(controls, mxlc, 12, "UInt") + NumPut(cbmc, mxlc, 16, "UInt") + NumPut(&mc, mxlc, 20, "Ptr") + + if (DllCall("winmm\mixerGetLineControlsW", "UInt", mixerID, "Ptr", &mxlc, "UInt", 0, "UInt") == 0) { + Loop %controls% { + control := A_Index - 1 + if (NumGet(mc, 8 + (control * cbmc), "UInt") == 1342373889) { ; volume control + Minimum := NumGet(mc, 180 + (control * cbmc), "UInt") + Maximum := NumGet(mc, 184 + (control * cbmc), "UInt") + Steps := NumGet(mc, 204 + (control * cbmc), "UInt") + volID := NumGet(mc, 4 + (control * cbmc), "UInt") + return True + } + } + } + } + } + } + } + } + } + + return False +} + +CLAMP(x, low, high) +{ + return (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) +} \ No newline at end of file diff --git a/startWindows10Calendar.ahk b/startWindows10Calendar.ahk new file mode 100644 index 0000000..437dc38 --- /dev/null +++ b/startWindows10Calendar.ahk @@ -0,0 +1,7 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. + +; AppUserID string source: https://stackoverflow.com/questions/32150759/how-to-enumerate-the-installed-storeapps-and-their-id-in-windows-8-and-10 +IApplicationActivationManager := ComObjCreate("{45BA127D-10A8-46EA-8AB7-56EA9078943C}", "{2e941141-7f97-4756-ba1d-9decde894a3d}") +DllCall(NumGet(NumGet(IApplicationActivationManager+0)+3*A_PtrSize), "Ptr", IApplicationActivationManager, "Str", "microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar", "Str", 0, "UInt", 0, "IntP", processId) +ObjRelease(IApplicationActivationManager) +ExitApp \ No newline at end of file