tinygoblin Posted November 28, 2022 Share Posted November 28, 2022 Hello! I'm having trouble with rather outdated AutoIt EXE which provides unique function of changing last write time value of Windows registry keys, SetRegKey. This software is fully open source, released in 2014 and there's no alternatives (like at all). The development appears to be abandoned. The problem is with recursion mechanism which is returns error in Windows 10 version 1607 and 21H2 while recursive mode works fin in Windows 7 SP1 (I tested everything). The regular mode works fine. I cannot figure out what's the problem because I'm new to AutoIt and both recursive and normal seem to use same function (NtOpenKey). Here're steps to reproduce issue in Windows 10 (same steps work correctly in Windows 7):1. Make sure there's a key in HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.a with sub-key HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.a\PersistentHandler 2. Launch SetRegTime 1.0.0.5 in recursive mode using -s switch to change last write time of that key and it's sub-key: SetRegTime64.exe "\Registry\Machine\Software\Classes\.a" "1976:01:01:00:00:00:000:0000" -s 3. This error message appears and the key timestamp stays unchanged: Generated timestamp: 118337760000000000 (1976:01:01:00:00:00:000:0000) Location: \Registry\Machine\Software\Classes\.a\PersistentHandler Error in NtOpenKey 3: 0xC0000034 -> The system cannot find the file specified. Job took 0 seconds If you use -n instead of -s in step 2 the timestamp of key "...\Classes\.a" is changed but timestamp of it's sub-key is not changed. Here's au3 code of same version 1.0.0.5 that is available at GitHub at the moment: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Res_Comment=Set LastWriteTime of keys in registry #AutoIt3Wrapper_Res_Description=Manipulate timestamps in the registry #AutoIt3Wrapper_Res_Fileversion=1.0.0.5 #AutoIt3Wrapper_Res_LegalCopyright=Joakim Schicht #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <String.au3> Global Const $__WINAPICONSTANT_FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100 Global Const $__WINAPICONSTANT_FORMAT_MESSAGE_FROM_SYSTEM = 0x1000 Global $DateTimeFormat = 6 Global Const $tagIOSTATUSBLOCK = "dword Status;ptr Information" Global Const $tagOBJECTATTRIBUTES = "ulong Length;hwnd RootDirectory;ptr ObjectName;ulong Attributes;ptr SecurityDescriptor;ptr SecurityQualityOfService" Global Const $tagUNICODESTRING = "ushort Length;ushort MaximumLength;ptr Buffer" Global Const $tagKEYWRITETIMEINFORMATION = "int64 LastWriteTime" Global Const $tagKEYBASICINFORMATION = "int64 LastWriteTime;ulong TitleIndex;ulong NameLength;wchar Name[400]" Global Const $KeyBasicInformation = 0 Global Const $OBJ_CASE_INSENSITIVE = 0x00000040 Global Const $KEY_READ = 0x20019 Global Const $KEY_WRITE = 0x20006 Global Const $KEY_CREATE_LINK = 0x0020 Global Const $KEY_ALL_ACCESS = 0xF003F Global Const $KEY_CREATE_SUB_KEY = 0x4 Global Const $KEY_ENUMERATE_SUB_KEYS = 0x8 Global Const $KEY_NOTIFY = 0x10 Global Const $KEY_QUERY_VALUE = 0x1 Global Const $REG_OPTION_NON_VOLATILE = 0x00000000 Global Const $KeyWriteTimeInformation = 0 Global Const $tagKEYNODEINFORMATION = "int64 LastWriteTime;ulong TitleIndex;ulong ClassOffset;ulong ClassLength;ulong NameLength;byte Name[2048]" Global Const $KeyNodeInformation = 1 Global $tDelta = _WinTime_GetUTCToLocalFileTimeDelta() Global $RootDir, $ObjName Global $Timerstart = TimerInit() ConsoleWrite("Starting SetRegTime by Joakim Schicht" & @CRLF) ConsoleWrite("Version 1.0.0.5" & @CRLF) ConsoleWrite("" & @CRLF) Global $hNTDLL = DllOpen("ntdll.dll") _validate_parameters() ConsoleWrite("Your current local time (timezone and/or daylight saving) is " & $tDelta / 36000000000 & " hours off UTC" & @CRLF) If $cmdline[0] = 1 Then If StringRight($cmdline[1],1) = "\" Then $RootDir = StringTrimRight($cmdline[1],1) Else $RootDir = $cmdline[1] EndIf $ObjectNames = StringSplit($RootDir,"\") Local $tmp For $i = 1 To Ubound($ObjectNames)-2 $tmp &= $ObjectNames[$i]&"\" Next $RootDir = StringTrimRight($tmp,1) If $ObjectNames[0] < 2 Then $ObjName = "" Else $ObjName = $ObjectNames[Ubound($ObjectNames)-1] EndIf $QueryKey = _NtQueryKey($RootDir, $ObjName, BitOR($KEY_QUERY_VALUE,$KEY_ENUMERATE_SUB_KEYS)) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($QueryKey,8) & @CRLF) Exit Else ConsoleWrite("The key: " & $QueryKey[0] & " has LastWriteTime timestamp: " & $QueryKey[1] & @CRLF) Exit EndIf EndIf $FormattedTimestamp = _ConfigTimestamp() If $FormattedTimestamp = -1 Then ConsoleWrite("Error: Timestamp generation failed" & @CRLF) Exit EndIf Global $NewTimestamp = StringMid($FormattedTimestamp[0],1,14) & $FormattedTimestamp[8] ConsoleWrite("Generated timestamp: " & $NewTimestamp & " ("&$cmdline[2]&")" & @CRLF) If $cmdline[3] = "-n" Then $RegKey = $cmdline[1] $hKey = _NtOpenKey($RegKey,BitOR($KEY_WRITE,$KEY_READ)) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($hKey,8) & @CRLF) Exit EndIf $SetTimestamp = _NtSetInformationKey($hKey,$KeyWriteTimeInformation,$NewTimestamp) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($SetTimestamp,8) & @CRLF) Exit EndIf $FlushKey = _NtFlushKey($hKey) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($FlushKey,8) & @CRLF) Exit EndIf ConsoleWrite("Successfully modified LastWriteTime on the key: " & $cmdline[1] & @CRLF) Exit ElseIf $cmdline[3] = "-s" Then If StringRight($cmdline[1],1) = "\" Then $RootDir = StringTrimRight($cmdline[1],1) Else $RootDir = $cmdline[1] EndIf $ObjectNames = StringSplit($RootDir,"\") Local $tmp For $i = 1 To Ubound($ObjectNames)-2 $tmp &= $ObjectNames[$i]&"\" Next $RootDir = StringTrimRight($tmp,1) If $ObjectNames[0] < 2 Then $ObjName = "" Else $ObjName = $ObjectNames[Ubound($ObjectNames)-1] EndIf _CheckSubKeys($RootDir, $ObjName) EndIf _End($Timerstart) ;DllCall($hNTDLL, "int", "NtClose", "hwnd", $hKey) DllClose($hNTDLL) Exit Func _NtSetInformationKey($handle,$KEY_SET_INFORMATION_CLASS,$timestamp) Local $sKWTI = DllStructCreate($tagKEYWRITETIMEINFORMATION) DllStructSetData($sKWTI,"LastWriteTime",$timestamp) Local $ret = DllCall($hNTDLL, "int", "NtSetInformationKey", "hwnd", $handle, "dword", $KEY_SET_INFORMATION_CLASS, "ptr", DllStructGetPtr($sKWTI), "dword", DllStructGetSize($sKWTI)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Error in NtSetInformationKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf EndFunc Func _NtFlushKey($KeyHandle) Local $ret = DllCall($hNTDLL, "int", "NtFlushKey", "hwnd", $KeyHandle) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Error in NtFlushKey" & @CRLF) Return SetError(1,0,$ret[0]) EndIf EndFunc Func _NtOpenKey($RegKey, $DesiredAccess) Local $Disposition, $ret, $KeyHandle Local $szName = DllStructCreate("wchar[260]") Local $sUS = DllStructCreate($tagUNICODESTRING) Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $sISB = DllStructCreate($tagIOSTATUSBLOCK) DllStructSetData($szName, 1, $RegKey) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", Chr(0)) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", Chr(0)) DllStructSetData($sOA, "SecurityQualityOfService", Chr(0)) Local $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", BitOR($KEY_WRITE,$KEY_READ), "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $RegKey & @CRLF) ConsoleWrite("Error in NtOpenKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf Return $ret[1] EndFunc Func NT_SUCCESS($status) If 0 <= $status And $status <= 0x7FFFFFFF Then Return True Else Return False EndIf EndFunc Func _LsaNtStatusToWinError($iNtStatus) Local $iSysError $iSysError = DllCall("Advapi32.dll", "ulong", "LsaNtStatusToWinError", "dword", $iNtStatus) Return $iSysError[0] EndFunc Func _ConfigTimestamp() Local $timestamp_array, $input2LocalFileTime[9] If StringLen($cmdline[2]) <> 28 Then ConsoleWrite("Error: Length of date/time is not correct: " & $cmdline[2] & @CRLF) Exit EndIf $timestamp_array = StringSplit(StringReplace($cmdline[2],'"',''),":") If $timestamp_array[0] <> 8 Then ConsoleWrite("Error: Not right date/time parameters supplied: " & $timestamp_array[0] & @CRLF) Exit EndIf For $dateinputs = 1 To $timestamp_array[0] If StringIsDigit($timestamp_array[$dateinputs]) <> 1 Then ConsoleWrite("Error: Not right date/time format supplied: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 2 And StringLen($timestamp_array[$dateinputs]) <> 4 And $dateinputs <> 7 Then ConsoleWrite("Error: Not right date/time format supplied: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 3 And $dateinputs = 7 Then ConsoleWrite("Error: Not right date/time format supplied for MilliSec: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 4 And $dateinputs = 8 Then ConsoleWrite("Error: Not right date/time format supplied for NanoSec: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf Next $input2LocalFileTime[0] = _WinTime_SystemTimeToLocalFileTime($timestamp_array[1],$timestamp_array[2],$timestamp_array[3],$timestamp_array[4],$timestamp_array[5],$timestamp_array[6],$timestamp_array[7],-1) $input2LocalFileTime[1] = $timestamp_array[1] $input2LocalFileTime[2] = $timestamp_array[2] $input2LocalFileTime[3] = $timestamp_array[3] $input2LocalFileTime[4] = $timestamp_array[4] $input2LocalFileTime[5] = $timestamp_array[5] $input2LocalFileTime[6] = $timestamp_array[6] $input2LocalFileTime[7] = $timestamp_array[7] $input2LocalFileTime[8] = $timestamp_array[8] Return $input2LocalFileTime EndFunc Func _FillZero($inp) Local $inplen, $out, $tmp = "" $inplen = StringLen($inp) For $i = 1 To 4-$inplen $tmp &= "0" Next $out = $tmp & $inp Return $out EndFunc Func _validate_parameters() If $cmdline[0] <> 3 AND $cmdline[0] <> 1 Then ConsoleWrite("Error: Incorrect number of parameters supplied: " & $cmdline[0] & @CRLF) ConsoleWrite("Examples:" & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Setting the LastWriteTime timestamp on a specific key under the the SOFTWARE key under HKLM:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine\Software\something" "2000:01:01:00:00:00:789:1234" -n' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Retrieving the LastWriteTime timestamp on the SOFTWARE key under HKLM:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine\Software"' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Setting the LastWriteTime timestamp recursively through the whole registry:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine" "2000:01:01:00:00:00:789:1234" -s' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Format of timestamp is important and will be interpreted as: YYYY:MM:DD:HH:MM:SS:MSMSMS:NSNSNSNS" & @CRLF) ConsoleWrite("Remember that timestamp supplied will be taken as UTC (not adjusted for timezone configuration)" & @CRLF) Exit EndIf EndFunc Func _NtQueryKey($RootDirectory, $ObjectName, $DesiredAccess, $NullChars=0) Local $SpecialRet[2] Local $Disposition, $ret, $KeyHandle Local $szName = DllStructCreate("wchar[260]") Local $sUS = DllStructCreate($tagUNICODESTRING) Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $sISB = DllStructCreate($tagIOSTATUSBLOCK) DllStructSetData($szName, 1, $RootDirectory) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", 0) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $DesiredAccess, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $RootDirectory & @CRLF) ConsoleWrite("Error in NtOpenKey 1 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf $handle = $ret[1] DllStructSetData($szName, 1, $ObjectName) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sUS,"Length",DllStructGetData($sUS,"Length")+$NullChars) DllStructSetData($sUS,"MaximumLength",DllStructGetData($sUS,"MaximumLength")+$NullChars) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", $handle) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $DesiredAccess, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $RootDirectory & "\" & $ObjectName & @CRLF) ConsoleWrite("Error in NtOpenKey 2 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf $handle = $ret[1] Local $sKBI = DllStructCreate($tagKEYBASICINFORMATION) Local $ResultLength Local $ret = DllCall($hNTDLL, "int", "NtQueryKey", "hwnd", $handle, "dword", $KeyBasicInformation, "ptr", DllStructGetPtr($sKBI), "dword", DllStructGetSize($sKBI), "ulong*", $ResultLength) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Error in NtQueryKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf $regLastWriteTime = DllStructGetData($sKBI,"LastWriteTime") $b = DllStructGetData($sKBI,"Title") $c = DllStructGetData($sKBI,"NameLength") $d = DllStructGetData($sKBI,"Name") $regLastWriteTime1 = _WinTime_UTCFileTimeFormat($regLastWriteTime-$tDelta,$DateTimeFormat,2) $regLastWriteTime2 = $regLastWriteTime1 & ":" & StringRight($regLastWriteTime,4) $regLastWriteTime3 = $regLastWriteTime1 & ":" & _FillZero(StringRight($regLastWriteTime,4)) $SpecialRet[0] = $d $SpecialRet[1] = $regLastWriteTime3 Return $SpecialRet EndFunc Func _CheckSubKeys($startkey, $subkey) ; ConsoleWrite("$startkey " & $startkey & @CRLF) Local $key, $found = "" Local $Disposition, $ret, $KeyHandle, $NameLengthDiff, $ResultLength, $Index, $handle, $handle2, $aCounter = 1, $aTmp Local $szName = DllStructCreate("wchar[260]") Local $sUS = DllStructCreate($tagUNICODESTRING) Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $sISB = DllStructCreate($tagIOSTATUSBLOCK) DllStructSetData($szName, 1, $startkey) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", 0) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $KEY_READ, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $startkey & @CRLF) ConsoleWrite("Error in NtOpenKey 1 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,0) EndIf $handle = $ret[1] DllStructSetData($szName, 1, $subkey) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", $handle) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $KEY_READ, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & @CRLF) ConsoleWrite("Error in NtOpenKey 2 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,0) EndIf $handle = $ret[1] $Index = 0 While 1 $sKI = DllStructCreate($tagKEYNODEINFORMATION) Local $ResultLength Local $ret = DllCall($hNTDLL, "int", "NtEnumerateKey", "hwnd", $handle, "dword", $Index, "dword", $KeyNodeInformation, "ptr", DllStructGetPtr($sKI), "dword", DllStructGetSize($sKI), "ulong*", $ResultLength) If Not NT_SUCCESS($ret[0]) And $ret[0] <> -2147483622 Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & " //$Index=" & $Index & @CRLF) ConsoleWrite("Error in NtEnumerateKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) If Hex($ret[0],8) = "C0000008" Then ExitLoop; STATUS_INVALID_HANDLE Return SetError(1,0,0) EndIf $NtStatus = "0x"&Hex($ret[0],8) If $NtStatus = "0x8000001A" Then ExitLoop ; STATUS_NO_MORE_ENTRIES $NameLength = DllStructGetData($sKI,"NameLength") $Name = DllStructGetData($sKI,"Name") $Name = StringMid($Name,3,$NameLength*2) Local $FormattedName = _HexToString(_RemoveUnicode($Name)) $TestChars = _FixUnicodeString($Name) $InvalidChars = $TestChars[0] $FixedChars = $TestChars[1] If $InvalidChars = 0 Then Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $szName = DllStructCreate("wchar[260]") ;--------------------RtlInitUnicodeString turned out to be 50% slower on average, so replaced it ; Local $sUS = DllStructCreate($tagUNICODESTRING) ; DllStructSetData($szName, 1, $FormattedName) ; $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) $NameLength = StringLen($Name)/2 Local $sUS = DllStructCreate("ushort Length;ushort MaximumLength;ptr Buffer") DllStructSetData($sUS,"Length",$NameLength) DllStructSetData($sUS,"MaximumLength",$NameLength+2) DllStructSetData($sUS,"Buffer",DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", $handle) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) Local $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $KEY_ALL_ACCESS, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & "\" & $FormattedName & @CRLF) ConsoleWrite("Error in NtOpenKey 3: 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) $Index += 1 ContinueLoop EndIf _NtSetInformationKey($ret[1],$KeyWriteTimeInformation,$NewTimestamp) EndIf _CheckSubKeys($startkey&"\"&$subkey,$FormattedName) $Index += 1 WEnd DllCall($hNTDLL, "int", "NtClose", "hwnd", $handle) EndFunc Func _FixUnicodeString($Inp) Local $InpLen, $Tmp, $Appended, $Counter=0, $Info[2] If StringLeft($Inp,2) = "0x" Then $Inp = StringMid($Inp,3) $InpLen = StringLen($Inp) For $i = 1 To $InpLen Step 4 $Tmp = StringMid($Inp,$i,2) ; If Dec($Tmp) = 0 Then If Dec($Tmp) < 32 Then; Replace all control characters too $Tmp = "2A" $Counter+=1 EndIf $Appended &= $Tmp Next $Info[0] = $Counter $Info[1] = $Appended Return $Info EndFunc Func _RtlNtStatusToDosError($Status) Local $aCall = DllCall("ntdll.dll", "ulong", "RtlNtStatusToDosError", "dword", $Status) If Not NT_SUCCESS($aCall[0]) Then ConsoleWrite("Error in RtlNtStatusToDosError: " & Hex($aCall[0], 8) & @CRLF) Return SetError(1, 0, $aCall[0]) Else Return $aCall[0] EndIf EndFunc Func _TranslateErrorCode($ErrCode) Local $tBufferPtr = DllStructCreate("ptr") Local $nCount = _FormatMessage(BitOR($__WINAPICONSTANT_FORMAT_MESSAGE_ALLOCATE_BUFFER, $__WINAPICONSTANT_FORMAT_MESSAGE_FROM_SYSTEM), _ 0, $ErrCode, 0, $tBufferPtr, 0, 0) If @error Then Return SetError(@error, 0, "") Local $sText = "" Local $pBuffer = DllStructGetData($tBufferPtr, 1) If $pBuffer Then If $nCount > 0 Then Local $tBuffer = DllStructCreate("wchar[" & ($nCount + 1) & "]", $pBuffer) $sText = DllStructGetData($tBuffer, 1) EndIf _LocalFree($pBuffer) EndIf Return $sText EndFunc Func _FormatMessage($iFlags, $pSource, $iMessageID, $iLanguageID, ByRef $pBuffer, $iSize, $vArguments) Local $sBufferType = "struct*" If IsString($pBuffer) Then $sBufferType = "wstr" Local $aResult = DllCall("Kernel32.dll", "dword", "FormatMessageW", "dword", $iFlags, "ptr", $pSource, "dword", $iMessageID, "dword", $iLanguageID, _ $sBufferType, $pBuffer, "dword", $iSize, "ptr", $vArguments) If @error Then Return SetError(@error, @extended, 0) If $sBufferType = "wstr" Then $pBuffer = $aResult[5] Return $aResult[0] EndFunc Func _LocalFree($hMem) Local $aResult = DllCall("kernel32.dll", "handle", "LocalFree", "handle", $hMem) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc Func _StrToUnicode($Inp) Local $InpLen, $Tmp, $Appended $InpLen = StringLen($Inp) For $i = 1 To $InpLen $Tmp = _StringToHex(StringMid($Inp,$i,1)) $Appended &= $Tmp&"00" Next Return $Appended EndFunc Func _HexToUnicode($Inp) Local $InpLen, $Tmp, $Appended $InpLen = StringLen($Inp) For $i = 1 To $InpLen Step 2 $Tmp = StringMid($Inp,$i,2) $Appended &= $Tmp&"00" Next Return $Appended EndFunc Func _RemoveUnicode($Inp) Local $InpLen, $Tmp, $Appended If StringLeft($Inp,2) = "0x" Then $Inp = StringMid($Inp,3) $InpLen = StringLen($Inp) For $i = 1 To $InpLen Step 4 $Tmp = StringMid($Inp,$i,2) $Appended &= $Tmp Next Return $Appended EndFunc Func _End($begin) Local $timerdiff = TimerDiff($begin) $timerdiff = Round(($timerdiff / 1000), 2) ConsoleWrite("Job took " & $timerdiff & " seconds" & @CRLF) ; Exit EndFunc #include-once ; =============================================================================================================================== ; <_WinTimeFunctions.au3> ; ; Functions for getting, converting, & formatting Windows 'FileTime's and 'SystemTime's ; NOTE - While they are referred to as 'Time's, the values do contain date information (when calculated appropriately) ; ; Functions: ; _WinTime_GetSystemTimeAsLocalFileTime() ; Gets Local SystemTime as a 64bit FileTime ; _WinTime_UTCFileTimeToLocalFileTime() ; Converts 64bit UTC FileTime to 64bit Local FileTime ; _WinTime_LocalFileTimeToUTCFileTime() ; Converts 64bit Local FileTime to 64bit UTC FileTime ; _WinTime_GetUTCToLocalFileTimeDelta() ; returns a FileTime Delta (for converting from UTC to Local FileTime w/o function calls) ; _WinTime_GetLocalToUTCFileTimeDelta() ; returns a FileTime Delta (for converting from Local to UTC FileTime w/o function calls) ; _WinTime_LocalFileTimeToSystemTime() ; Converts Local FileTime to a SystemTime array ; _WinTime_SystemTimeToLocalFileTime() ; Converts SystemTime values to 64bit Local FileTime ; _WinTime_FormatTime() ; Returns a formatted string/array representing date/time using numerical parameters ; _WinTime_FormatSysTimeArray() ; Returns a formatted string/array using a SystemTime array (from _WinTime_LocalFileTimeToSystemTime()) ; _WinTime_LocalFileTimeFormat() ; Returns a formatted string/array based on Local SystemTime conversion ; _WinTime_LocalFileTimeFormatBasic() ; - Basic version of the above - returns either an array or a 'YYYYMMDDHHMMSS' string ; _WinTime_UTCFileTimeFormat() ; Returns a formatted string/array based on UTC-to-*Local* SystemTime conversion ; _WinTime_UTCFileTimeFormatBasic() ; - Basic version of the above - returns either an array or a 'YYYYMMDDHHMMSS' string ; _WinTime_AddToFileTime() ; Function to perform limited addition/subtraction on FileTimes ; ; (add limits: Days(+Weeks),Hours,Minutes,Seconds,Milliseconds,& Nanoseconds) ; ; Included, but could also instead use standard UDF: ; _WinTime_IsLeapYear() ; Given a Year, will return True/False if it is a leap year (standard UDF: _DateIsLeapYear()) ; ; Considered, but better option might be standard UDF's?: ; _WinTime_DaysInMonth() ; _DateDaysInMonth() standard UDF.. NOTE: uses _DateIsLeapYear() standard UDF too! ; _WinTime_AddDays/Years/Months ; _DateAdd() standard UDF might be easiest option - also uses a number of other UDF's too ; ; Retired Functions: ; _WinTime_CompareFileTime() ; This can be performed using simple logic compares ; ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; So, what *ARE* Window's FileTime and SystemTime value/structures? ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; *FileTime* is a 64-bit unsigned value representing the # of 100-nanosecond intervals since January 1, 1601 ; This standard can be utilized in two forms: ; UTC Time (coordinated universal time), also referred to as GMT (Greenwich Mean\Meridian Time) ; Local Time (time that is adjusted for the current time-zone/locale, calculated as an offset from UTC time) ; ; Within Windows, there is a minimum & maximum value for FileTime, as follows [Note output's special case]: ; Minimum = 0x0 (0): January 1, 1601 00:00:00:0000 (UTC) *Local Date/Time may vary slightly ; Maximum = ; (Input): 0x7FFF35F4F06C58F0 (9,223,149,887,999,990,000): December 31,30827 @ 23:59:59:999 ; (Output): 0x7FFFFFFFFFFFE950 (9,223,372,036,854,770,000): September 13, 30828 @ 22:48:05:0477 (UTC)* ; *Output's *Local* Date/Time may vary slightly - though max # stays same ; ; *SystemTime* is an array of information regarding the System Time, with a precision down to milliseconds. ; The array includes Year,Month,DayOfWeek,Day,Hour,Minute,Second, and Millisecond ; The extra 'DayOfWeek' item is provided to help determine if it is Sunday (0) through Saturday (6) ; ; - FileTime and SystemTime can be converted to/from each other ; - SystemTime should only be used with *Local* FileTime functions, ; unless it is known beforehand that UTC FileTime is needed\being obtained ; - FileTime can be converted to/from both UTC and Local time-zone/locales ; ; For more info, see individual Function Headers ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; See also: ; <WinTimeFunctionsTest.au3> ; tests for these functions ; <_WinAPI_FileFind.au3> ; new version requires this module ; <_ProcessFunctions.au3> ; _ProcessGetTimes() needs this for conversion ; <_ProcesListFunctions.au3> ; <_ProcessUndocumented.au3> ; <_WinAPI_GetProcessCreateTime.au3> ; older module ; <_WinAPI_FileTimeConvert32.au3> ; early 32-bit early version of _WinTime_UTCFileTimeFormat() ; ; Author: Ascend4nt ; =============================================================================================================================== ; =================================================================================================================== ; -------------------- GLOBAL COMMON DLL HANDLE -------------------- ; =================================================================================================================== Global $_COMMON_KERNEL32DLL=DllOpen("kernel32.dll") ; DLLClose() will be done automatically on exit. [this doesn't reload the DLL] ; =============================================================================================================================== ; Func _WinTime_GetSystemTimeAsLocalFileTime() ; ; Function to grab the current system time as 64bit Local FileTime (not UTC) ; ; Return: ; Success: 64-bit value representing the UTC-based FileTime ; Failure: -1, with @error set: ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_GetSystemTimeAsLocalFileTime() Local $aRet=DllCall($_COMMON_KERNEL32DLL,"none","GetSystemTimeAsFileTime","uint64*",0) If @error Then Return SetError(2,@error,-1) Return $aRet[1] EndFunc ; =============================================================================================================================== ; Func _WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) ; ; Convert 64bit UTC FileTime to 64bit Local FileTime ; ; $iUTCFileTime = 64bit UTC FileTime to convert to Local FileTime ; ; Returns: ; Success: 64bit value in Local FileTime (converted from UTC FileTime) ; Failure: -1 with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If $iUTCFileTime<0 Then Return SetError(1,0,-1) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","FileTimeToLocalFileTime","uint64*",$iUTCFileTime,"uint64*",0) If @error Then Return SetError(2,@error,-1) If Not $aRet[0] Then Return SetError(3,0,-1) Return $aRet[2] EndFunc ; =============================================================================================================================== ; Func _WinTime_GetUTCToLocalFileTimeDelta() ; ; Returns the Delta value the system uses in calculating the offset in going from UTC to Local FileTime ; (this should always be in hours, so dividing by 36000000000 will give the # hours offset) ; ; This function is intended to both serve as a means to cut back on DLL calls & provide an easy answer to the difference ; between UTC & Local FileTime's ; ; Example results: If PC's Locale is Eastern Time (say, NYC), and Daylight Savings Time is in effect, the result would be ; -144000000000 (or, /36000000000 = -4 hours). So 7pm UTC/GMT = 3pm NYC [Local] time. ; w/o Daylight savings, would be -5 hours, so 7pm UTC/GMT = 2pm NYC [Local] time. ; ; Returns: ; Success: 64bit FileTime 'offset' value ; Failure: -1 with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_GetUTCToLocalFileTimeDelta() Local $iUTCFileTime=864000000000 ; exactly 24 hours from the origin (although 12 hours would be more appropriate (max variance = 12)) $iLocalFileTime=_WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If @error Then Return SetError(@error,@extended,-1) Return $iLocalFileTime-$iUTCFileTime ; /36000000000 = # hours delta (effectively giving the offset in hours from UTC/GMT) EndFunc ; =============================================================================================================================== ; Func _WinTime_GetLocalToUTCFileTimeDelta() ; ; Returns the Delta value the system uses in calculating the offset in going from Local to UTC FileTime ; (this should always be in hours, so dividing by 36000000000 will give the # hours offset) ; ; This function is intended to both serve as a means to cut back on DLL calls & provide an easy answer to the difference ; between Local & UTC FileTime's ; ; Example results: If PC's Locale is Eastern Time (say, NYC), and Daylight Savings Time is in effect, the result would be ; +144000000000 (or, /36000000000 = +4 hours). So 3pm NYC [Local] time = 7pm UTC/GMT time. ; w/o Daylight savings, would be +5 hours, so 2pm NYC [Local] time = 7pm UTC/GMT time. ; ; Returns: ; Success: 64bit FileTime 'offset' value ; Failure: -1 with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_GetLocalToUTCFileTimeDelta() ; All we need to do is negate the results of this function: Local $iDelta=_WinTime_GetUTCToLocalFileTimeDelta() If @error Then Return SetError(@error,@extended,-1) Return -$iDelta ; divide by 36000000000 = # hours delta (effectively giving the offset in hours from UTC/GMT) EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeToUTCFileTime($iLocalFileTime) ; ; Convert a Local 64bit FileTime value to a 64bit UTC FileTime value (universal time) ; ; $iLocalFileTime = local FileTime, as a 64bit value ; ; Returns: ; Success: 64bit value in UTC FileTime ; Failure: -1 with @error set: ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeToUTCFileTime($iLocalFileTime) If $iLocalFileTime<0 Then Return SetError(1,0,-1) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","LocalFileTimeToFileTime","uint64*",$iLocalFileTime,"uint64*",0) If @error Then Return SetError(2,@error,-1) If Not $aRet[0] Then Return SetError(3,0,-1) Return $aRet[2] EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeToSystemTime($iLocalFileTime) ; ; Convert a 64bit Local FileTime to a 'Local Time' SystemTime array. ; ; $iLocalFileTime = 64bit Local FileTime (not UTC) to convert to a SystemTime structure ; ; Returns: ; Success: 8 element array filled with values from a SystemTime struct: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (*not* day-of-the-week) (1-31) ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; Failure: 8-element array filled with-1's, with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeToSystemTime($iLocalFileTime) Local $aRet,$stSysTime,$aSysTime[8]=[-1,-1,-1,-1,-1,-1,-1,-1] ; Negative values unacceptable If $iLocalFileTime<0 Then Return SetError(1,0,$aSysTime) ; SYSTEMTIME structure [Year,Month,DayOfWeek,Day,Hour,Min,Sec,Milliseconds] $stSysTime=DllStructCreate("ushort[8]") $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","FileTimeToSystemTime","uint64*",$iLocalFileTime,"ptr",DllStructGetPtr($stSysTime)) If @error Then Return SetError(2,@error,$aSysTime) If Not $aRet[0] Then Return SetError(3,0,$aSysTime) Dim $aSysTime[8]=[DllStructGetData($stSysTime,1,1),DllStructGetData($stSysTime,1,2),DllStructGetData($stSysTime,1,4),DllStructGetData($stSysTime,1,5), _ DllStructGetData($stSysTime,1,6),DllStructGetData($stSysTime,1,7),DllStructGetData($stSysTime,1,8),DllStructGetData($stSysTime,1,3)] Return $aSysTime EndFunc ; =============================================================================================================================== ; Func _WinTime_SystemTimeToLocalFileTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek=-1) ; ; Convert System Time numerical values to a Local FileTime (64-bit value), and returns the result ; NOTE: It doesn't *have* to be a *Local* FileTime, but that is typically the use for this function ; ; NOTE Regarding Variables: These are NUMERICAL values. ; Only 1 check is done (for year), so be sure to pass correct values. Valid Ranges in parentheses: ; $iYear = year (1601 -> 30827) ; $iMonth = month (1 (Jan) - 12 (Dec)) ; $iDay = day of the month (1-31) ; $iHour = hour (0-23 [24-hour military clock]) ; $iMin = minutes (0-59) ; $iSec = seconds (0-59) ; $iMilSec = milliseconds (0-999) ; $iDayOfWeek = day of week (-1 (don't know/care), 0 (Sunday) - 6 (Saturday)). ; If $iDayOfWeek = -1, Windows will automatically figure out the appropriate day ; ; Returns: ; Success: 64bit value in Local FileTime (not UTC) ; Failure: -1 with @error set: ; @error = 1 = Invalid param(s) *Currently only checks that year is >0 and <30828 ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_SystemTimeToLocalFileTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek=-1) ; Least\Greatest year check If $iYear<1601 Or $iYear>30827 Then Return SetError(1,0,-1) ; SYSTEMTIME structure [Year,Month,DayOfWeek,Day,Hour,Min,Sec,Milliseconds] Local $stSysTime=DllStructCreate("ushort[8]") DllStructSetData($stSysTime,1,$iYear,1) DllStructSetData($stSysTime,1,$iMonth,2) DllStructSetData($stSysTime,1,$iDayOfWeek,3) DllStructSetData($stSysTime,1,$iDay,4) DllStructSetData($stSysTime,1,$iHour,5) DllStructSetData($stSysTime,1,$iMin,6) DllStructSetData($stSysTime,1,$iSec,7) DllStructSetData($stSysTime,1,$iMilSec,8) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","SystemTimeToFileTime","ptr",DllStructGetPtr($stSysTime),"int64*",0) If @error Then Return SetError(2,@error,-1) If Not $aRet[0] Then Return SetError(3,0,-1) Return $aRet[2] EndFunc ; =============================================================================================================================== ; Func _WinTime_FormatTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts the given parameters to a formatted string, or a 3-element array of formatted strings based on parameters ; NOTE: In a speed-sensitive loop, it may be better to create a string using numbers, padding, and PCRE's ; ; $iYear = year (any #, but SystemTime's range is 1601 -> 30827/30828) ; $iMonth = month (1 (Jan) - 12 (Dec)) ; $iDay = day of the month (1-31) ; $iHour = hour (0-23 [24-hour military clock]) ; $iMin = minutes (0-59) ; $iSec = seconds (0-59) ; $iMilSec = milliseconds (0-999) ; $iDayOfWeek = day of week (-1 (don't know/care), 0 (Sunday) - 6 (Saturday)). *Only used when $iFormat +8 and/or +16 used ; If $iDayOfWeek = -1, $iFormat of +8 shouldn't be used, and for +16, DayOfWeek (array[2]) will = "" ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 - Returns "" *here for $iFormat compatibility with _WinTime_FormatSysTimeArray()'s parameter ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: String, or array, @error = 0 ; Failure: "" with @error set to 1 for invalid params ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_FormatTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) Local Static $_WT_aMonths[12]=["January","February","March","April","May","June","July","August","September","October","November","December"] Local Static $_WT_aDays[7]=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"] If Not $iFormat Or $iMonth<1 Or $iMonth>12 Or $iDayOfWeek>6 Then Return SetError(1,0,"") ; Pad MM,DD,HH,MM,SS,MSMSMSMS as necessary Local $sMM=StringRight(0&$iMonth,2),$sDD=StringRight(0&$iDay,2),$sMin=StringRight(0&$iMin,2) ; $sYY = $iYear ; (no padding) ; [technically Year can be 1-x chars - but this is generally used for 4-digit years. And SystemTime only goes up to 30827/30828] Local $sHH,$sSS,$sMS,$sAMPM ; 'Extra precision 1': +SS (Seconds) If $iPrecision Then $sSS=StringRight(0&$iSec,2) ; 'Extra precision 2': +MSMSMSMS (Milliseconds) If $iPrecision>1 Then ; $sMS=StringRight('000'&$iMilSec,4) $sMS=StringRight('000'&$iMilSec,3);Fixed an erronous 0 in front of the milliseconds Else $sMS="" EndIf Else $sSS="" $sMS="" EndIf If $bAMPMConversion Then If $iHour>11 Then $sAMPM=" PM" ; 12 PM will cause 12-12 to equal 0, so avoid the calculation: If $iHour=12 Then $sHH="12" Else $sHH=StringRight(0&($iHour-12),2) EndIf Else $sAMPM=" AM" If $iHour Then $sHH=StringRight(0&$iHour,2) Else ; 00 military = 12 AM $sHH="12" EndIf EndIf Else $sAMPM="" $sHH=StringRight(0 & $iHour,2) EndIf Local $sDateTimeStr,$aReturnArray[3] ; Return an array? [formatted string + "Month" + "DayOfWeek"] If BitAND($iFormat,0x10) Then $aReturnArray[1]=$_WT_aMonths[$iMonth-1] If $iDayOfWeek>=0 Then $aReturnArray[2]=$_WT_aDays[$iDayOfWeek] Else $aReturnArray[2]="" EndIf ; Strip the 'array' bit off (array[1] will now indicate if an array is to be returned) $iFormat=BitAND($iFormat,0xF) Else ; Signal to below that the array isn't to be returned $aReturnArray[1]="" EndIf ; Prefix with "DayOfWeek "? If BitAND($iFormat,8) Then If $iDayOfWeek<0 Then Return SetError(1,0,"") ; invalid $sDateTimeStr=$_WT_aDays[$iDayOfWeek]&', ' ; Strip the 'DayOfWeek' bit off $iFormat=BitAND($iFormat,0x7) Else $sDateTimeStr="" EndIf If $iFormat<2 Then ; Basic String format: YYYYMMDDHHMM[SS[MSMSMSMS[ AM/PM]]] $sDateTimeStr&=$iYear&$sMM&$sDD&$sHH&$sMin&$sSS&$sMS&$sAMPM Else ; one of 4 formats which ends with " HH:MM[:SS[:MSMSMSMS[ AM/PM]]]" Switch $iFormat ; /, : Format - MM/DD/YYYY Case 2 $sDateTimeStr&=$sMM&'/'&$sDD&'/' ; /, : alt. Format - DD/MM/YYYY Case 3 $sDateTimeStr&=$sDD&'/'&$sMM&'/' ; "Month DD, YYYY" format Case 4 $sDateTimeStr&=$_WT_aMonths[$iMonth-1]&' '&$sDD&', ' ; "DD Month YYYY" format Case 5 $sDateTimeStr&=$sDD&' '&$_WT_aMonths[$iMonth-1]&' ' Case 6 $sDateTimeStr&=$iYear&'-'&$sMM&'-'&$sDD $iYear='' Case Else Return SetError(1,0,"") EndSwitch $sDateTimeStr&=$iYear&' '&$sHH&':'&$sMin If $iPrecision Then $sDateTimeStr&=':'&$sSS If $iPrecision>1 Then $sDateTimeStr&=':'&$sMS EndIf $sDateTimeStr&=$sAMPM EndIf If $aReturnArray[1]<>"" Then $aReturnArray[0]=$sDateTimeStr Return $aReturnArray EndIf Return $sDateTimeStr EndFunc ; =============================================================================================================================== ; Func _WinTime_FormatSysTimeArray(ByRef $aSysTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts a System Time array (as returned from _WinTime_LocalFileTimeToSystemTime()) ; to an array, a formatted string, or a 3-element array of formatted strings based on parameters ; ; $aSysTime = 8 element SystemTime array returned from _WinTime_LocalFileTimeToSystemTime() ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format (returns what is passed to it - for compatibility with _WinTime_LocalFileTimeFormat()'s $iFormat) ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: String, or array, @error = 0 ; Failure: "" with @error set to 1 for invalid params ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_FormatSysTimeArray(ByRef $aSysTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) If Not IsArray($aSysTime) Then Return SetError(1,0,"") ; Or UBound($aSysTime)<8 Then Return SetError(1,0,"") If $aSysTime[0]=-1 Then Return SetError(1,0,"") ; When called by _WinTime_LocalFileTimeFormat() If Not $iFormat Then Return $aSysTime Local $vReturn=_WinTime_FormatTime($aSysTime[0],$aSysTime[1],$aSysTime[2],$aSysTime[3], _ $aSysTime[4],$aSysTime[5],$aSysTime[6],$aSysTime[7],$iFormat,$iPrecision,$bAMPMConversion) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeFormat($iLocalFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts Local FileTime to a *Local* SystemTime formatted value. ; Returns either an array, a formatted string, or a 3-element array of formatted strings ; ; $iLocalFileTime = 64-bit *Local* FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: Converted/Formatted Array, String, or Array-of-Strings ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeFormat($iLocalFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ;~ If $iLocalFileTime<0 Then Return SetError(1,0,"") ; checked in below call ; Convert file time to a system time array & return result Local $aSysTime=_WinTime_LocalFileTimeToSystemTime($iLocalFileTime) If @error Then Return SetError(@error,@extended,"") ; Return only the SystemTime array? If $iFormat=0 Then Return $aSysTime Local $vReturn=_WinTime_FormatTime($aSysTime[0],$aSysTime[1],$aSysTime[2],$aSysTime[3], _ $aSysTime[4],$aSysTime[5],$aSysTime[6],$aSysTime[7],$iFormat,$iPrecision,$bAMPMConversion) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeFormatBasic($iLocalFileTime,$iFormat=0) ; ; 'Basic' version of above function (used to cut down on size/speed where needed): ; Converts Local FileTime to a *Local* SystemTime formatted value, returning 1 of 2 formats: ; - an array, or ; - a string in 'YYYYMMDDHHMMSS' format ; ; $iLocalFileTime = 64-bit *Local* FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1: Main String's format: YYYYMMDDHHMMSS ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; ; Returns: ; Success: Converted/Formatted Array or String, with @error = 0 ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeFormatBasic($iLocalFileTime,$iFormat=0) ;~ If $iLocalFileTime<0 Then Return SetError(1,0,"") ; checked in below call ; Convert file time to a system time array & return result Local $aSysTime=_WinTime_LocalFileTimeToSystemTime($iLocalFileTime) If @error Then Return SetError(@error,@extended,"") ; Return only the SystemTime array? If $iFormat=0 Then Return $aSysTime ; No - return 'YYYYMMDDHHMMSS' string format: Return $aSysTime[0]&StringRight(0&$aSysTime[1],2)&StringRight(0&$aSysTime[2],2)&StringRight(0&$aSysTime[3],2)&StringRight(0&$aSysTime[4],2)&StringRight(0&$aSysTime[5],2) ; This is 'nicer' but slower than the above: ;~ Return $aSysTime[0]&StringFormat("%02u%02u%02u%02u%02u",$aSysTime[1],$aSysTime[2],$aSysTime[3],$aSysTime[4],$aSysTime[5]) EndFunc ; =============================================================================================================================== ; Func _WinTime_UTCFileTimeFormat($iUTCFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts UTC FileTime to a formatted *Local* SystemTime value ; Returns either an array, a formatted string, or a 3-element array of formatted strings ; ; NOTE: When used with _WinAPI_FileFind.. functions, the *PREFERRED* METHOD of calling this is: ; _WinAPI_FileFindTimeConvert() ; ; $iUTCFileTime = 64-bit UTC FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: Converted/Formatted Array, String, or Array-of-Strings ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_UTCFileTimeFormat($iUTCFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ;~ If $iUTCFileTime<0 Then Return SetError(1,0,"") ; checked in below call ; First convert file time (UTC-based file time) to 'local file time' Local $iLocalFileTime=_WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If @error Then Return SetError(@error,@extended,"") ; Rare occassion: a filetime near the origin (January 1, 1601!!) is used, ; causing a negative result (for some timezones). Return as invalid param. If $iLocalFileTime<0 Then Return SetError(1,0,"") ; Then convert file time to a system time array & format & return it Local $vReturn=_WinTime_LocalFileTimeFormat($iLocalFileTime,$iFormat,$iPrecision,$bAMPMConversion) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_UTCFileTimeFormatBasic($iUTCFileTime,$iFormat=0) ; ; 'Basic' version of above function (used to cut down on size/speed where needed): ; Converts UTC FileTime to a *Local* SystemTime formatted value, returning 1 of 2 formats: ; - an array, or ; - a string in 'YYYYMMDDHHMMSS' format ; ; $iUTCFileTime = 64-bit UTC FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1: Main String's format: YYYYMMDDHHMMSS ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; ; Returns: ; Success: Converted/Formatted Array or String & @error=0 ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_UTCFileTimeFormatBasic($iUTCFileTime,$iFormat=0) ; First convert file time (UTC-based file time) to 'local file time' Local $vReturn,$iLocalFileTime=_WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If @error Then Return SetError(@error,@extended,"") ; Rare occassion: a filetime near the origin (January 1, 1601!!) is used, ; causing a negative result (for some timezones). Return as invalid param. If $iLocalFileTime<0 Then Return SetError(1,0,"") ; Then convert file time to a system time array & format & return it $vReturn=_WinTime_LocalFileTimeFormatBasic($iLocalFileTime,$iFormat) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_AddToFileTime($iFileTime,$iDay=0,$iHour=0,$iMin=0,$iSec=0,$iMilSec=0,$iNanoSec=0) ; ; Function to add/subtract time/days to a FileTime value, with restrictions. ; (Months & Years are not allowed as parameters because of the calculations and needed knowledge about ; both leap year and the month that the FileTime represents, and what the calculation will pass by) ; ; $iFileTime = 64bit FileTime, either UTC or Local, to add/subtract to ; $iDay = # of days to add/subtract (using positive or negative #'s) ; $iHour = # of hours "" "" ; $iMin = # of minutes "" "" ; $iSec = # of seconds "" "" ; $iMilSec = # of milliseconds "" "" ; $iNanoSec = # of nanoseconds "" "" - NOTE: this will be divided by 100, as 100-nsecond intervals are the smallest allowable #s ; ; * FOR WEEKS * : in $iDay, add (#OfWeeks * 7) to rest of equation ; ; NOTES Regaring Limitations: ; Year is *NOT* easily added without taking into account leap years. To calculate such values, ; the FileTime must be converted to UTC SystemTime, then a calculation would need to be done to ; figure out if there is/will-be leap year(s). Then the leap years would be 366, non = 365. ; Ideally it would be ($iYear*365*24*60*60*10000000), but thats not taking into accout 366-day leap years ; ; ALSO, Month is *NOT* easily figured out without knowing which month you are currently on, how many ; days in each month to add, whether there is or will be leap year(s) , and so on. ; Ideally it would be something like ($iMonth*30*24*60*60*10000000), but non-30 day months and extra-day leap-years are ignored ; ; For those needs, read into the _DateAdd() UDF ; ; Additional NOTE Regarding Nanoseconds: ; These can be added (and will be divided by 100 as explained above), but will *only* have a *noticeable* effect if ; the add/subtract causes a rollover to occur in Milliseconds. ; Reason: when converted to SystemTime, the highest precision reported is Milliseconds ; ; Returns: ; Success: New modified 64-bit FileTime ; Failure: -1, with @error set to 1 (invalid parameter) ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_AddToFileTime($iFileTime,$iDay,$iHour=0,$iMin=0,$iSec=0,$iMilSec=0,$iNanoSec=0) If $iFileTime<0 Then return SetError(1,0,-1) ; Less calculations way: Return $iFileTime+($iDay*864000000000)+($iHour*36000000000)+($iMin*600000000)+($iSec*10000000)+($iMilSec*10000)+Round($iNanoSec/100) ; More readable\understandable way: ;Return $iFileTime+($iDay*24*60*60*10000000)+($iHour*60*60*10000000)+($iMin*60*10000000)+($iSec*10000000)+ _ ; ($iMilSec*10000)+Round($iNanoSec/100) EndFunc ; =============================================================================================================================== ; Func _WinTime_IsLeapYear($iYear) ; ; Simple calculation based on numerical input (Year) to determine if it is a leap year (366 day year (29 days in February)) ; ; $iYear = year to check ; ; Returns: ; Success: True/False, with @error = 0. (True = IS leap year, False = is NOT) ; Failure: False with @error = 1 (invalid param) ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_IsLeapYear($iYear) If $iYear<0 Then Return SetError(1,1,False) ; Divisible by 4 and not evenly divisible by 100: GOOD If BitAND($iYear,3)=0 And Mod($iYear,100) Then Return True ; Evenly divisible by 400? (which also implies evenly divisible by 100, and 4), also good. If Mod($iYear,400)=0 Then Return True ; None of the above (either not divisible by 4, or divisible by 100 and not by 400. [or not a number]) Return False EndFunc #region WINTIME_RETIRED_FUNCTIONS #cs ; - RETIRED FUNCTION - ; =============================================================================================================================== ; Func _WinTime_CompareFileTime($iTimeA,$iTimeB) ; ; Function to compare two 64bit FileTime values. This allows <, =, and > returns. ; ; NOTE: This can be done using basic 64bit compares, so the point of this function is moot. ; ; $iTimeA = 1st 64bit FileTime value ; $iTimeB = 2nd 64bit FileTime value ; ; Return: ; Success: -1,0,or 1: ; -1 means $iTimeA < $iTimeB ($iTimeA is *earlier* than $iTimeB) ; 0 means $iTimeA == $iTimeB ($iTimeA is *EQUAL* to $iTimeB) ; 1 means $iTimeA > $iTimeB ($iTimeA is *later* than $iTimeB) ; Failure: 0, with @error set: ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_CompareFileTime($iTimeA,$iTimeB) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"long","CompareFileTime","uint64*",$iTimeA,"uint64*",$iTimeB) If @error Then Return SetError(2,@error,0) Return $aRet[0] EndFunc ; - END RETIRED FUNCTION - #ce #endregion This is the original code of version 1.0.0.5 was originally released on August 30, 2014 at Google Code, it consists of 2 parts: SetRegTime.au3 expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Res_Comment=Set LastWriteTime of keys in registry #AutoIt3Wrapper_Res_Description=Manipulate timestamps in the registry #AutoIt3Wrapper_Res_Fileversion=1.0.0.5 #AutoIt3Wrapper_Res_LegalCopyright=Joakim Schicht #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include "_WinTimeFunctions2.au3" #include <String.au3> Global Const $__WINAPICONSTANT_FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100 Global Const $__WINAPICONSTANT_FORMAT_MESSAGE_FROM_SYSTEM = 0x1000 Global $DateTimeFormat = 6 Global Const $tagIOSTATUSBLOCK = "dword Status;ptr Information" Global Const $tagOBJECTATTRIBUTES = "ulong Length;hwnd RootDirectory;ptr ObjectName;ulong Attributes;ptr SecurityDescriptor;ptr SecurityQualityOfService" Global Const $tagUNICODESTRING = "ushort Length;ushort MaximumLength;ptr Buffer" Global Const $tagKEYWRITETIMEINFORMATION = "int64 LastWriteTime" Global Const $tagKEYBASICINFORMATION = "int64 LastWriteTime;ulong TitleIndex;ulong NameLength;wchar Name[400]" Global Const $KeyBasicInformation = 0 Global Const $OBJ_CASE_INSENSITIVE = 0x00000040 Global Const $KEY_READ = 0x20019 Global Const $KEY_WRITE = 0x20006 Global Const $KEY_CREATE_LINK = 0x0020 Global Const $KEY_ALL_ACCESS = 0xF003F Global Const $KEY_CREATE_SUB_KEY = 0x4 Global Const $KEY_ENUMERATE_SUB_KEYS = 0x8 Global Const $KEY_NOTIFY = 0x10 Global Const $KEY_QUERY_VALUE = 0x1 Global Const $REG_OPTION_NON_VOLATILE = 0x00000000 Global Const $KeyWriteTimeInformation = 0 Global Const $tagKEYNODEINFORMATION = "int64 LastWriteTime;ulong TitleIndex;ulong ClassOffset;ulong ClassLength;ulong NameLength;byte Name[2048]" Global Const $KeyNodeInformation = 1 Global $tDelta = _WinTime_GetUTCToLocalFileTimeDelta() Global $RootDir, $ObjName Global $Timerstart = TimerInit() ConsoleWrite("Starting SetRegTime by Joakim Schicht" & @CRLF) ConsoleWrite("Version 1.0.0.5" & @CRLF) ConsoleWrite("" & @CRLF) Global $hNTDLL = DllOpen("ntdll.dll") _validate_parameters() ConsoleWrite("Your current local time (timezone and/or daylight saving) is " & $tDelta / 36000000000 & " hours off UTC" & @CRLF) If $cmdline[0] = 1 Then If StringRight($cmdline[1],1) = "\" Then $RootDir = StringTrimRight($cmdline[1],1) Else $RootDir = $cmdline[1] EndIf $ObjectNames = StringSplit($RootDir,"\") Local $tmp For $i = 1 To Ubound($ObjectNames)-2 $tmp &= $ObjectNames[$i]&"\" Next $RootDir = StringTrimRight($tmp,1) If $ObjectNames[0] < 2 Then $ObjName = "" Else $ObjName = $ObjectNames[Ubound($ObjectNames)-1] EndIf $QueryKey = _NtQueryKey($RootDir, $ObjName, BitOR($KEY_QUERY_VALUE,$KEY_ENUMERATE_SUB_KEYS)) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($QueryKey,8) & @CRLF) Exit Else ConsoleWrite("The key: " & $QueryKey[0] & " has LastWriteTime timestamp: " & $QueryKey[1] & @CRLF) Exit EndIf EndIf $FormattedTimestamp = _ConfigTimestamp() If $FormattedTimestamp = -1 Then ConsoleWrite("Error: Timestamp generation failed" & @CRLF) Exit EndIf Global $NewTimestamp = StringMid($FormattedTimestamp[0],1,14) & $FormattedTimestamp[8] ConsoleWrite("Generated timestamp: " & $NewTimestamp & " ("&$cmdline[2]&")" & @CRLF) If $cmdline[3] = "-n" Then $RegKey = $cmdline[1] $hKey = _NtOpenKey($RegKey,BitOR($KEY_WRITE,$KEY_READ)) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($hKey,8) & @CRLF) Exit EndIf $SetTimestamp = _NtSetInformationKey($hKey,$KeyWriteTimeInformation,$NewTimestamp) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($SetTimestamp,8) & @CRLF) Exit EndIf $FlushKey = _NtFlushKey($hKey) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($FlushKey,8) & @CRLF) Exit EndIf ConsoleWrite("Successfully modified LastWriteTime on the key: " & $cmdline[1] & @CRLF) Exit ElseIf $cmdline[3] = "-s" Then If StringRight($cmdline[1],1) = "\" Then $RootDir = StringTrimRight($cmdline[1],1) Else $RootDir = $cmdline[1] EndIf $ObjectNames = StringSplit($RootDir,"\") Local $tmp For $i = 1 To Ubound($ObjectNames)-2 $tmp &= $ObjectNames[$i]&"\" Next $RootDir = StringTrimRight($tmp,1) If $ObjectNames[0] < 2 Then $ObjName = "" Else $ObjName = $ObjectNames[Ubound($ObjectNames)-1] EndIf _CheckSubKeys($RootDir, $ObjName) EndIf _End($Timerstart) ;DllCall($hNTDLL, "int", "NtClose", "hwnd", $hKey) DllClose($hNTDLL) Exit Func _NtSetInformationKey($handle,$KEY_SET_INFORMATION_CLASS,$timestamp) Local $sKWTI = DllStructCreate($tagKEYWRITETIMEINFORMATION) DllStructSetData($sKWTI,"LastWriteTime",$timestamp) Local $ret = DllCall($hNTDLL, "int", "NtSetInformationKey", "hwnd", $handle, "dword", $KEY_SET_INFORMATION_CLASS, "ptr", DllStructGetPtr($sKWTI), "dword", DllStructGetSize($sKWTI)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Error in NtSetInformationKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf EndFunc Func _NtFlushKey($KeyHandle) Local $ret = DllCall($hNTDLL, "int", "NtFlushKey", "hwnd", $KeyHandle) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Error in NtFlushKey" & @CRLF) Return SetError(1,0,$ret[0]) EndIf EndFunc Func _NtOpenKey($RegKey, $DesiredAccess) Local $Disposition, $ret, $KeyHandle Local $szName = DllStructCreate("wchar[260]") Local $sUS = DllStructCreate($tagUNICODESTRING) Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $sISB = DllStructCreate($tagIOSTATUSBLOCK) DllStructSetData($szName, 1, $RegKey) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", Chr(0)) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", Chr(0)) DllStructSetData($sOA, "SecurityQualityOfService", Chr(0)) Local $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", BitOR($KEY_WRITE,$KEY_READ), "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $RegKey & @CRLF) ConsoleWrite("Error in NtOpenKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf Return $ret[1] EndFunc Func NT_SUCCESS($status) If 0 <= $status And $status <= 0x7FFFFFFF Then Return True Else Return False EndIf EndFunc Func _LsaNtStatusToWinError($iNtStatus) Local $iSysError $iSysError = DllCall("Advapi32.dll", "ulong", "LsaNtStatusToWinError", "dword", $iNtStatus) Return $iSysError[0] EndFunc Func _ConfigTimestamp() Local $timestamp_array, $input2LocalFileTime[9] If StringLen($cmdline[2]) <> 28 Then ConsoleWrite("Error: Length of date/time is not correct: " & $cmdline[2] & @CRLF) Exit EndIf $timestamp_array = StringSplit(StringReplace($cmdline[2],'"',''),":") If $timestamp_array[0] <> 8 Then ConsoleWrite("Error: Not right date/time parameters supplied: " & $timestamp_array[0] & @CRLF) Exit EndIf For $dateinputs = 1 To $timestamp_array[0] If StringIsDigit($timestamp_array[$dateinputs]) <> 1 Then ConsoleWrite("Error: Not right date/time format supplied: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 2 And StringLen($timestamp_array[$dateinputs]) <> 4 And $dateinputs <> 7 Then ConsoleWrite("Error: Not right date/time format supplied: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 3 And $dateinputs = 7 Then ConsoleWrite("Error: Not right date/time format supplied for MilliSec: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 4 And $dateinputs = 8 Then ConsoleWrite("Error: Not right date/time format supplied for NanoSec: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf Next $input2LocalFileTime[0] = _WinTime_SystemTimeToLocalFileTime($timestamp_array[1],$timestamp_array[2],$timestamp_array[3],$timestamp_array[4],$timestamp_array[5],$timestamp_array[6],$timestamp_array[7],-1) $input2LocalFileTime[1] = $timestamp_array[1] $input2LocalFileTime[2] = $timestamp_array[2] $input2LocalFileTime[3] = $timestamp_array[3] $input2LocalFileTime[4] = $timestamp_array[4] $input2LocalFileTime[5] = $timestamp_array[5] $input2LocalFileTime[6] = $timestamp_array[6] $input2LocalFileTime[7] = $timestamp_array[7] $input2LocalFileTime[8] = $timestamp_array[8] Return $input2LocalFileTime EndFunc Func _FillZero($inp) Local $inplen, $out, $tmp = "" $inplen = StringLen($inp) For $i = 1 To 4-$inplen $tmp &= "0" Next $out = $tmp & $inp Return $out EndFunc Func _validate_parameters() If $cmdline[0] <> 3 AND $cmdline[0] <> 1 Then ConsoleWrite("Error: Incorrect number of parameters supplied: " & $cmdline[0] & @CRLF) ConsoleWrite("Examples:" & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Setting the LastWriteTime timestamp on a specific key under the the SOFTWARE key under HKLM:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine\Software\something" "2000:01:01:00:00:00:789:1234" -n' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Retrieving the LastWriteTime timestamp on the SOFTWARE key under HKLM:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine\Software"' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Setting the LastWriteTime timestamp recursively through the whole registry:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine" "2000:01:01:00:00:00:789:1234" -s' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Format of timestamp is important and will be interpreted as: YYYY:MM:DD:HH:MM:SS:MSMSMS:NSNSNSNS" & @CRLF) ConsoleWrite("Remember that timestamp supplied will be taken as UTC (not adjusted for timezone configuration)" & @CRLF) Exit EndIf EndFunc Func _NtQueryKey($RootDirectory, $ObjectName, $DesiredAccess, $NullChars=0) Local $SpecialRet[2] Local $Disposition, $ret, $KeyHandle Local $szName = DllStructCreate("wchar[260]") Local $sUS = DllStructCreate($tagUNICODESTRING) Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $sISB = DllStructCreate($tagIOSTATUSBLOCK) DllStructSetData($szName, 1, $RootDirectory) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", 0) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $DesiredAccess, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $RootDirectory & @CRLF) ConsoleWrite("Error in NtOpenKey 1 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf $handle = $ret[1] DllStructSetData($szName, 1, $ObjectName) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sUS,"Length",DllStructGetData($sUS,"Length")+$NullChars) DllStructSetData($sUS,"MaximumLength",DllStructGetData($sUS,"MaximumLength")+$NullChars) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", $handle) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $DesiredAccess, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $RootDirectory & "\" & $ObjectName & @CRLF) ConsoleWrite("Error in NtOpenKey 2 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf $handle = $ret[1] Local $sKBI = DllStructCreate($tagKEYBASICINFORMATION) Local $ResultLength Local $ret = DllCall($hNTDLL, "int", "NtQueryKey", "hwnd", $handle, "dword", $KeyBasicInformation, "ptr", DllStructGetPtr($sKBI), "dword", DllStructGetSize($sKBI), "ulong*", $ResultLength) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Error in NtQueryKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,$ret[0]) EndIf $regLastWriteTime = DllStructGetData($sKBI,"LastWriteTime") $b = DllStructGetData($sKBI,"Title") $c = DllStructGetData($sKBI,"NameLength") $d = DllStructGetData($sKBI,"Name") $regLastWriteTime1 = _WinTime_UTCFileTimeFormat($regLastWriteTime-$tDelta,$DateTimeFormat,2) $regLastWriteTime2 = $regLastWriteTime1 & ":" & StringRight($regLastWriteTime,4) $regLastWriteTime3 = $regLastWriteTime1 & ":" & _FillZero(StringRight($regLastWriteTime,4)) $SpecialRet[0] = $d $SpecialRet[1] = $regLastWriteTime3 Return $SpecialRet EndFunc Func _CheckSubKeys($startkey, $subkey) ; ConsoleWrite("$startkey " & $startkey & @CRLF) Local $key, $found = "" Local $Disposition, $ret, $KeyHandle, $NameLengthDiff, $ResultLength, $Index, $handle, $handle2, $aCounter = 1, $aTmp Local $szName = DllStructCreate("wchar[260]") Local $sUS = DllStructCreate($tagUNICODESTRING) Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $sISB = DllStructCreate($tagIOSTATUSBLOCK) DllStructSetData($szName, 1, $startkey) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", 0) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $KEY_READ, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $startkey & @CRLF) ConsoleWrite("Error in NtOpenKey 1 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,0) EndIf $handle = $ret[1] DllStructSetData($szName, 1, $subkey) $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", $handle) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $KEY_READ, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & @CRLF) ConsoleWrite("Error in NtOpenKey 2 : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) Return SetError(1,0,0) EndIf $handle = $ret[1] $Index = 0 While 1 $sKI = DllStructCreate($tagKEYNODEINFORMATION) Local $ResultLength Local $ret = DllCall($hNTDLL, "int", "NtEnumerateKey", "hwnd", $handle, "dword", $Index, "dword", $KeyNodeInformation, "ptr", DllStructGetPtr($sKI), "dword", DllStructGetSize($sKI), "ulong*", $ResultLength) If Not NT_SUCCESS($ret[0]) And $ret[0] <> -2147483622 Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & " //$Index=" & $Index & @CRLF) ConsoleWrite("Error in NtEnumerateKey : 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) If Hex($ret[0],8) = "C0000008" Then ExitLoop; STATUS_INVALID_HANDLE Return SetError(1,0,0) EndIf $NtStatus = "0x"&Hex($ret[0],8) If $NtStatus = "0x8000001A" Then ExitLoop ; STATUS_NO_MORE_ENTRIES $NameLength = DllStructGetData($sKI,"NameLength") $Name = DllStructGetData($sKI,"Name") $Name = StringMid($Name,3,$NameLength*2) Local $FormattedName = _HexToString(_RemoveUnicode($Name)) $TestChars = _FixUnicodeString($Name) $InvalidChars = $TestChars[0] $FixedChars = $TestChars[1] If $InvalidChars = 0 Then Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES) Local $szName = DllStructCreate("wchar[260]") ;--------------------RtlInitUnicodeString turned out to be 50% slower on average, so replaced it ; Local $sUS = DllStructCreate($tagUNICODESTRING) ; DllStructSetData($szName, 1, $FormattedName) ; $ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName)) $NameLength = StringLen($Name)/2 Local $sUS = DllStructCreate("ushort Length;ushort MaximumLength;ptr Buffer") DllStructSetData($sUS,"Length",$NameLength) DllStructSetData($sUS,"MaximumLength",$NameLength+2) DllStructSetData($sUS,"Buffer",DllStructGetPtr($szName)) DllStructSetData($sOA, "Length", DllStructGetSize($sOA)) DllStructSetData($sOA, "RootDirectory", $handle) DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS)) DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE) DllStructSetData($sOA, "SecurityDescriptor", 0) DllStructSetData($sOA, "SecurityQualityOfService", 0) Local $ret = DllCall($hNTDLL, "int", "NtOpenKey", "hwnd*", "", "dword", $KEY_ALL_ACCESS, "ptr", DllStructGetPtr($sOA)) If Not NT_SUCCESS($ret[0]) Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & "\" & $FormattedName & @CRLF) ConsoleWrite("Error in NtOpenKey 3: 0x"&Hex($ret[0],8) &" -> "& _TranslateErrorCode(_RtlNtStatusToDosError("0x"&Hex($ret[0],8))) & @CRLF) $Index += 1 ContinueLoop EndIf _NtSetInformationKey($ret[1],$KeyWriteTimeInformation,$NewTimestamp) EndIf _CheckSubKeys($startkey&"\"&$subkey,$FormattedName) $Index += 1 WEnd DllCall($hNTDLL, "int", "NtClose", "hwnd", $handle) EndFunc Func _FixUnicodeString($Inp) Local $InpLen, $Tmp, $Appended, $Counter=0, $Info[2] If StringLeft($Inp,2) = "0x" Then $Inp = StringMid($Inp,3) $InpLen = StringLen($Inp) For $i = 1 To $InpLen Step 4 $Tmp = StringMid($Inp,$i,2) ; If Dec($Tmp) = 0 Then If Dec($Tmp) < 32 Then; Replace all control characters too $Tmp = "2A" $Counter+=1 EndIf $Appended &= $Tmp Next $Info[0] = $Counter $Info[1] = $Appended Return $Info EndFunc Func _RtlNtStatusToDosError($Status) Local $aCall = DllCall("ntdll.dll", "ulong", "RtlNtStatusToDosError", "dword", $Status) If Not NT_SUCCESS($aCall[0]) Then ConsoleWrite("Error in RtlNtStatusToDosError: " & Hex($aCall[0], 8) & @CRLF) Return SetError(1, 0, $aCall[0]) Else Return $aCall[0] EndIf EndFunc Func _TranslateErrorCode($ErrCode) Local $tBufferPtr = DllStructCreate("ptr") Local $nCount = _FormatMessage(BitOR($__WINAPICONSTANT_FORMAT_MESSAGE_ALLOCATE_BUFFER, $__WINAPICONSTANT_FORMAT_MESSAGE_FROM_SYSTEM), _ 0, $ErrCode, 0, $tBufferPtr, 0, 0) If @error Then Return SetError(@error, 0, "") Local $sText = "" Local $pBuffer = DllStructGetData($tBufferPtr, 1) If $pBuffer Then If $nCount > 0 Then Local $tBuffer = DllStructCreate("wchar[" & ($nCount + 1) & "]", $pBuffer) $sText = DllStructGetData($tBuffer, 1) EndIf _LocalFree($pBuffer) EndIf Return $sText EndFunc Func _FormatMessage($iFlags, $pSource, $iMessageID, $iLanguageID, ByRef $pBuffer, $iSize, $vArguments) Local $sBufferType = "struct*" If IsString($pBuffer) Then $sBufferType = "wstr" Local $aResult = DllCall("Kernel32.dll", "dword", "FormatMessageW", "dword", $iFlags, "ptr", $pSource, "dword", $iMessageID, "dword", $iLanguageID, _ $sBufferType, $pBuffer, "dword", $iSize, "ptr", $vArguments) If @error Then Return SetError(@error, @extended, 0) If $sBufferType = "wstr" Then $pBuffer = $aResult[5] Return $aResult[0] EndFunc Func _LocalFree($hMem) Local $aResult = DllCall("kernel32.dll", "handle", "LocalFree", "handle", $hMem) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc Func _StrToUnicode($Inp) Local $InpLen, $Tmp, $Appended $InpLen = StringLen($Inp) For $i = 1 To $InpLen $Tmp = _StringToHex(StringMid($Inp,$i,1)) $Appended &= $Tmp&"00" Next Return $Appended EndFunc Func _HexToUnicode($Inp) Local $InpLen, $Tmp, $Appended $InpLen = StringLen($Inp) For $i = 1 To $InpLen Step 2 $Tmp = StringMid($Inp,$i,2) $Appended &= $Tmp&"00" Next Return $Appended EndFunc Func _RemoveUnicode($Inp) Local $InpLen, $Tmp, $Appended If StringLeft($Inp,2) = "0x" Then $Inp = StringMid($Inp,3) $InpLen = StringLen($Inp) For $i = 1 To $InpLen Step 4 $Tmp = StringMid($Inp,$i,2) $Appended &= $Tmp Next Return $Appended EndFunc Func _End($begin) Local $timerdiff = TimerDiff($begin) $timerdiff = Round(($timerdiff / 1000), 2) ConsoleWrite("Job took " & $timerdiff & " seconds" & @CRLF) ; Exit EndFunc _WinTimeFunctions2.au3 expandcollapse popup#include-once ; =============================================================================================================================== ; <_WinTimeFunctions.au3> ; ; Functions for getting, converting, & formatting Windows 'FileTime's and 'SystemTime's ; NOTE - While they are referred to as 'Time's, the values do contain date information (when calculated appropriately) ; ; Functions: ; _WinTime_GetSystemTimeAsLocalFileTime() ; Gets Local SystemTime as a 64bit FileTime ; _WinTime_UTCFileTimeToLocalFileTime() ; Converts 64bit UTC FileTime to 64bit Local FileTime ; _WinTime_LocalFileTimeToUTCFileTime() ; Converts 64bit Local FileTime to 64bit UTC FileTime ; _WinTime_GetUTCToLocalFileTimeDelta() ; returns a FileTime Delta (for converting from UTC to Local FileTime w/o function calls) ; _WinTime_GetLocalToUTCFileTimeDelta() ; returns a FileTime Delta (for converting from Local to UTC FileTime w/o function calls) ; _WinTime_LocalFileTimeToSystemTime() ; Converts Local FileTime to a SystemTime array ; _WinTime_SystemTimeToLocalFileTime() ; Converts SystemTime values to 64bit Local FileTime ; _WinTime_FormatTime() ; Returns a formatted string/array representing date/time using numerical parameters ; _WinTime_FormatSysTimeArray() ; Returns a formatted string/array using a SystemTime array (from _WinTime_LocalFileTimeToSystemTime()) ; _WinTime_LocalFileTimeFormat() ; Returns a formatted string/array based on Local SystemTime conversion ; _WinTime_LocalFileTimeFormatBasic() ; - Basic version of the above - returns either an array or a 'YYYYMMDDHHMMSS' string ; _WinTime_UTCFileTimeFormat() ; Returns a formatted string/array based on UTC-to-*Local* SystemTime conversion ; _WinTime_UTCFileTimeFormatBasic() ; - Basic version of the above - returns either an array or a 'YYYYMMDDHHMMSS' string ; _WinTime_AddToFileTime() ; Function to perform limited addition/subtraction on FileTimes ; ; (add limits: Days(+Weeks),Hours,Minutes,Seconds,Milliseconds,& Nanoseconds) ; ; Included, but could also instead use standard UDF: ; _WinTime_IsLeapYear() ; Given a Year, will return True/False if it is a leap year (standard UDF: _DateIsLeapYear()) ; ; Considered, but better option might be standard UDF's?: ; _WinTime_DaysInMonth() ; _DateDaysInMonth() standard UDF.. NOTE: uses _DateIsLeapYear() standard UDF too! ; _WinTime_AddDays/Years/Months ; _DateAdd() standard UDF might be easiest option - also uses a number of other UDF's too ; ; Retired Functions: ; _WinTime_CompareFileTime() ; This can be performed using simple logic compares ; ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; So, what *ARE* Window's FileTime and SystemTime value/structures? ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; *FileTime* is a 64-bit unsigned value representing the # of 100-nanosecond intervals since January 1, 1601 ; This standard can be utilized in two forms: ; UTC Time (coordinated universal time), also referred to as GMT (Greenwich Mean\Meridian Time) ; Local Time (time that is adjusted for the current time-zone/locale, calculated as an offset from UTC time) ; ; Within Windows, there is a minimum & maximum value for FileTime, as follows [Note output's special case]: ; Minimum = 0x0 (0): January 1, 1601 00:00:00:0000 (UTC) *Local Date/Time may vary slightly ; Maximum = ; (Input): 0x7FFF35F4F06C58F0 (9,223,149,887,999,990,000): December 31,30827 @ 23:59:59:999 ; (Output): 0x7FFFFFFFFFFFE950 (9,223,372,036,854,770,000): September 13, 30828 @ 22:48:05:0477 (UTC)* ; *Output's *Local* Date/Time may vary slightly - though max # stays same ; ; *SystemTime* is an array of information regarding the System Time, with a precision down to milliseconds. ; The array includes Year,Month,DayOfWeek,Day,Hour,Minute,Second, and Millisecond ; The extra 'DayOfWeek' item is provided to help determine if it is Sunday (0) through Saturday (6) ; ; - FileTime and SystemTime can be converted to/from each other ; - SystemTime should only be used with *Local* FileTime functions, ; unless it is known beforehand that UTC FileTime is needed\being obtained ; - FileTime can be converted to/from both UTC and Local time-zone/locales ; ; For more info, see individual Function Headers ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; See also: ; <WinTimeFunctionsTest.au3> ; tests for these functions ; <_WinAPI_FileFind.au3> ; new version requires this module ; <_ProcessFunctions.au3> ; _ProcessGetTimes() needs this for conversion ; <_ProcesListFunctions.au3> ; <_ProcessUndocumented.au3> ; <_WinAPI_GetProcessCreateTime.au3> ; older module ; <_WinAPI_FileTimeConvert32.au3> ; early 32-bit early version of _WinTime_UTCFileTimeFormat() ; ; Author: Ascend4nt ; =============================================================================================================================== ; =================================================================================================================== ; -------------------- GLOBAL COMMON DLL HANDLE -------------------- ; =================================================================================================================== Global $_COMMON_KERNEL32DLL=DllOpen("kernel32.dll") ; DLLClose() will be done automatically on exit. [this doesn't reload the DLL] ; =============================================================================================================================== ; Func _WinTime_GetSystemTimeAsLocalFileTime() ; ; Function to grab the current system time as 64bit Local FileTime (not UTC) ; ; Return: ; Success: 64-bit value representing the UTC-based FileTime ; Failure: -1, with @error set: ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_GetSystemTimeAsLocalFileTime() Local $aRet=DllCall($_COMMON_KERNEL32DLL,"none","GetSystemTimeAsFileTime","uint64*",0) If @error Then Return SetError(2,@error,-1) Return $aRet[1] EndFunc ; =============================================================================================================================== ; Func _WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) ; ; Convert 64bit UTC FileTime to 64bit Local FileTime ; ; $iUTCFileTime = 64bit UTC FileTime to convert to Local FileTime ; ; Returns: ; Success: 64bit value in Local FileTime (converted from UTC FileTime) ; Failure: -1 with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If $iUTCFileTime<0 Then Return SetError(1,0,-1) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","FileTimeToLocalFileTime","uint64*",$iUTCFileTime,"uint64*",0) If @error Then Return SetError(2,@error,-1) If Not $aRet[0] Then Return SetError(3,0,-1) Return $aRet[2] EndFunc ; =============================================================================================================================== ; Func _WinTime_GetUTCToLocalFileTimeDelta() ; ; Returns the Delta value the system uses in calculating the offset in going from UTC to Local FileTime ; (this should always be in hours, so dividing by 36000000000 will give the # hours offset) ; ; This function is intended to both serve as a means to cut back on DLL calls & provide an easy answer to the difference ; between UTC & Local FileTime's ; ; Example results: If PC's Locale is Eastern Time (say, NYC), and Daylight Savings Time is in effect, the result would be ; -144000000000 (or, /36000000000 = -4 hours). So 7pm UTC/GMT = 3pm NYC [Local] time. ; w/o Daylight savings, would be -5 hours, so 7pm UTC/GMT = 2pm NYC [Local] time. ; ; Returns: ; Success: 64bit FileTime 'offset' value ; Failure: -1 with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_GetUTCToLocalFileTimeDelta() Local $iUTCFileTime=864000000000 ; exactly 24 hours from the origin (although 12 hours would be more appropriate (max variance = 12)) $iLocalFileTime=_WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If @error Then Return SetError(@error,@extended,-1) Return $iLocalFileTime-$iUTCFileTime ; /36000000000 = # hours delta (effectively giving the offset in hours from UTC/GMT) EndFunc ; =============================================================================================================================== ; Func _WinTime_GetLocalToUTCFileTimeDelta() ; ; Returns the Delta value the system uses in calculating the offset in going from Local to UTC FileTime ; (this should always be in hours, so dividing by 36000000000 will give the # hours offset) ; ; This function is intended to both serve as a means to cut back on DLL calls & provide an easy answer to the difference ; between Local & UTC FileTime's ; ; Example results: If PC's Locale is Eastern Time (say, NYC), and Daylight Savings Time is in effect, the result would be ; +144000000000 (or, /36000000000 = +4 hours). So 3pm NYC [Local] time = 7pm UTC/GMT time. ; w/o Daylight savings, would be +5 hours, so 2pm NYC [Local] time = 7pm UTC/GMT time. ; ; Returns: ; Success: 64bit FileTime 'offset' value ; Failure: -1 with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_GetLocalToUTCFileTimeDelta() ; All we need to do is negate the results of this function: Local $iDelta=_WinTime_GetUTCToLocalFileTimeDelta() If @error Then Return SetError(@error,@extended,-1) Return -$iDelta ; divide by 36000000000 = # hours delta (effectively giving the offset in hours from UTC/GMT) EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeToUTCFileTime($iLocalFileTime) ; ; Convert a Local 64bit FileTime value to a 64bit UTC FileTime value (universal time) ; ; $iLocalFileTime = local FileTime, as a 64bit value ; ; Returns: ; Success: 64bit value in UTC FileTime ; Failure: -1 with @error set: ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeToUTCFileTime($iLocalFileTime) If $iLocalFileTime<0 Then Return SetError(1,0,-1) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","LocalFileTimeToFileTime","uint64*",$iLocalFileTime,"uint64*",0) If @error Then Return SetError(2,@error,-1) If Not $aRet[0] Then Return SetError(3,0,-1) Return $aRet[2] EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeToSystemTime($iLocalFileTime) ; ; Convert a 64bit Local FileTime to a 'Local Time' SystemTime array. ; ; $iLocalFileTime = 64bit Local FileTime (not UTC) to convert to a SystemTime structure ; ; Returns: ; Success: 8 element array filled with values from a SystemTime struct: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (*not* day-of-the-week) (1-31) ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; Failure: 8-element array filled with-1's, with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeToSystemTime($iLocalFileTime) Local $aRet,$stSysTime,$aSysTime[8]=[-1,-1,-1,-1,-1,-1,-1,-1] ; Negative values unacceptable If $iLocalFileTime<0 Then Return SetError(1,0,$aSysTime) ; SYSTEMTIME structure [Year,Month,DayOfWeek,Day,Hour,Min,Sec,Milliseconds] $stSysTime=DllStructCreate("ushort[8]") $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","FileTimeToSystemTime","uint64*",$iLocalFileTime,"ptr",DllStructGetPtr($stSysTime)) If @error Then Return SetError(2,@error,$aSysTime) If Not $aRet[0] Then Return SetError(3,0,$aSysTime) Dim $aSysTime[8]=[DllStructGetData($stSysTime,1,1),DllStructGetData($stSysTime,1,2),DllStructGetData($stSysTime,1,4),DllStructGetData($stSysTime,1,5), _ DllStructGetData($stSysTime,1,6),DllStructGetData($stSysTime,1,7),DllStructGetData($stSysTime,1,8),DllStructGetData($stSysTime,1,3)] Return $aSysTime EndFunc ; =============================================================================================================================== ; Func _WinTime_SystemTimeToLocalFileTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek=-1) ; ; Convert System Time numerical values to a Local FileTime (64-bit value), and returns the result ; NOTE: It doesn't *have* to be a *Local* FileTime, but that is typically the use for this function ; ; NOTE Regarding Variables: These are NUMERICAL values. ; Only 1 check is done (for year), so be sure to pass correct values. Valid Ranges in parentheses: ; $iYear = year (1601 -> 30827) ; $iMonth = month (1 (Jan) - 12 (Dec)) ; $iDay = day of the month (1-31) ; $iHour = hour (0-23 [24-hour military clock]) ; $iMin = minutes (0-59) ; $iSec = seconds (0-59) ; $iMilSec = milliseconds (0-999) ; $iDayOfWeek = day of week (-1 (don't know/care), 0 (Sunday) - 6 (Saturday)). ; If $iDayOfWeek = -1, Windows will automatically figure out the appropriate day ; ; Returns: ; Success: 64bit value in Local FileTime (not UTC) ; Failure: -1 with @error set: ; @error = 1 = Invalid param(s) *Currently only checks that year is >0 and <30828 ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_SystemTimeToLocalFileTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek=-1) ; Least\Greatest year check If $iYear<1601 Or $iYear>30827 Then Return SetError(1,0,-1) ; SYSTEMTIME structure [Year,Month,DayOfWeek,Day,Hour,Min,Sec,Milliseconds] Local $stSysTime=DllStructCreate("ushort[8]") DllStructSetData($stSysTime,1,$iYear,1) DllStructSetData($stSysTime,1,$iMonth,2) DllStructSetData($stSysTime,1,$iDayOfWeek,3) DllStructSetData($stSysTime,1,$iDay,4) DllStructSetData($stSysTime,1,$iHour,5) DllStructSetData($stSysTime,1,$iMin,6) DllStructSetData($stSysTime,1,$iSec,7) DllStructSetData($stSysTime,1,$iMilSec,8) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"bool","SystemTimeToFileTime","ptr",DllStructGetPtr($stSysTime),"int64*",0) If @error Then Return SetError(2,@error,-1) If Not $aRet[0] Then Return SetError(3,0,-1) Return $aRet[2] EndFunc ; =============================================================================================================================== ; Func _WinTime_FormatTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts the given parameters to a formatted string, or a 3-element array of formatted strings based on parameters ; NOTE: In a speed-sensitive loop, it may be better to create a string using numbers, padding, and PCRE's ; ; $iYear = year (any #, but SystemTime's range is 1601 -> 30827/30828) ; $iMonth = month (1 (Jan) - 12 (Dec)) ; $iDay = day of the month (1-31) ; $iHour = hour (0-23 [24-hour military clock]) ; $iMin = minutes (0-59) ; $iSec = seconds (0-59) ; $iMilSec = milliseconds (0-999) ; $iDayOfWeek = day of week (-1 (don't know/care), 0 (Sunday) - 6 (Saturday)). *Only used when $iFormat +8 and/or +16 used ; If $iDayOfWeek = -1, $iFormat of +8 shouldn't be used, and for +16, DayOfWeek (array[2]) will = "" ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 - Returns "" *here for $iFormat compatibility with _WinTime_FormatSysTimeArray()'s parameter ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: String, or array, @error = 0 ; Failure: "" with @error set to 1 for invalid params ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_FormatTime($iYear,$iMonth,$iDay,$iHour,$iMin,$iSec,$iMilSec,$iDayOfWeek,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) Local Static $_WT_aMonths[12]=["January","February","March","April","May","June","July","August","September","October","November","December"] Local Static $_WT_aDays[7]=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"] If Not $iFormat Or $iMonth<1 Or $iMonth>12 Or $iDayOfWeek>6 Then Return SetError(1,0,"") ; Pad MM,DD,HH,MM,SS,MSMSMSMS as necessary Local $sMM=StringRight(0&$iMonth,2),$sDD=StringRight(0&$iDay,2),$sMin=StringRight(0&$iMin,2) ; $sYY = $iYear ; (no padding) ; [technically Year can be 1-x chars - but this is generally used for 4-digit years. And SystemTime only goes up to 30827/30828] Local $sHH,$sSS,$sMS,$sAMPM ; 'Extra precision 1': +SS (Seconds) If $iPrecision Then $sSS=StringRight(0&$iSec,2) ; 'Extra precision 2': +MSMSMSMS (Milliseconds) If $iPrecision>1 Then ; $sMS=StringRight('000'&$iMilSec,4) $sMS=StringRight('000'&$iMilSec,3);Fixed an erronous 0 in front of the milliseconds Else $sMS="" EndIf Else $sSS="" $sMS="" EndIf If $bAMPMConversion Then If $iHour>11 Then $sAMPM=" PM" ; 12 PM will cause 12-12 to equal 0, so avoid the calculation: If $iHour=12 Then $sHH="12" Else $sHH=StringRight(0&($iHour-12),2) EndIf Else $sAMPM=" AM" If $iHour Then $sHH=StringRight(0&$iHour,2) Else ; 00 military = 12 AM $sHH="12" EndIf EndIf Else $sAMPM="" $sHH=StringRight(0 & $iHour,2) EndIf Local $sDateTimeStr,$aReturnArray[3] ; Return an array? [formatted string + "Month" + "DayOfWeek"] If BitAND($iFormat,0x10) Then $aReturnArray[1]=$_WT_aMonths[$iMonth-1] If $iDayOfWeek>=0 Then $aReturnArray[2]=$_WT_aDays[$iDayOfWeek] Else $aReturnArray[2]="" EndIf ; Strip the 'array' bit off (array[1] will now indicate if an array is to be returned) $iFormat=BitAND($iFormat,0xF) Else ; Signal to below that the array isn't to be returned $aReturnArray[1]="" EndIf ; Prefix with "DayOfWeek "? If BitAND($iFormat,8) Then If $iDayOfWeek<0 Then Return SetError(1,0,"") ; invalid $sDateTimeStr=$_WT_aDays[$iDayOfWeek]&', ' ; Strip the 'DayOfWeek' bit off $iFormat=BitAND($iFormat,0x7) Else $sDateTimeStr="" EndIf If $iFormat<2 Then ; Basic String format: YYYYMMDDHHMM[SS[MSMSMSMS[ AM/PM]]] $sDateTimeStr&=$iYear&$sMM&$sDD&$sHH&$sMin&$sSS&$sMS&$sAMPM Else ; one of 4 formats which ends with " HH:MM[:SS[:MSMSMSMS[ AM/PM]]]" Switch $iFormat ; /, : Format - MM/DD/YYYY Case 2 $sDateTimeStr&=$sMM&'/'&$sDD&'/' ; /, : alt. Format - DD/MM/YYYY Case 3 $sDateTimeStr&=$sDD&'/'&$sMM&'/' ; "Month DD, YYYY" format Case 4 $sDateTimeStr&=$_WT_aMonths[$iMonth-1]&' '&$sDD&', ' ; "DD Month YYYY" format Case 5 $sDateTimeStr&=$sDD&' '&$_WT_aMonths[$iMonth-1]&' ' Case 6 $sDateTimeStr&=$iYear&'-'&$sMM&'-'&$sDD $iYear='' Case Else Return SetError(1,0,"") EndSwitch $sDateTimeStr&=$iYear&' '&$sHH&':'&$sMin If $iPrecision Then $sDateTimeStr&=':'&$sSS If $iPrecision>1 Then $sDateTimeStr&=':'&$sMS EndIf $sDateTimeStr&=$sAMPM EndIf If $aReturnArray[1]<>"" Then $aReturnArray[0]=$sDateTimeStr Return $aReturnArray EndIf Return $sDateTimeStr EndFunc ; =============================================================================================================================== ; Func _WinTime_FormatSysTimeArray(ByRef $aSysTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts a System Time array (as returned from _WinTime_LocalFileTimeToSystemTime()) ; to an array, a formatted string, or a 3-element array of formatted strings based on parameters ; ; $aSysTime = 8 element SystemTime array returned from _WinTime_LocalFileTimeToSystemTime() ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format (returns what is passed to it - for compatibility with _WinTime_LocalFileTimeFormat()'s $iFormat) ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: String, or array, @error = 0 ; Failure: "" with @error set to 1 for invalid params ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_FormatSysTimeArray(ByRef $aSysTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) If Not IsArray($aSysTime) Then Return SetError(1,0,"") ; Or UBound($aSysTime)<8 Then Return SetError(1,0,"") If $aSysTime[0]=-1 Then Return SetError(1,0,"") ; When called by _WinTime_LocalFileTimeFormat() If Not $iFormat Then Return $aSysTime Local $vReturn=_WinTime_FormatTime($aSysTime[0],$aSysTime[1],$aSysTime[2],$aSysTime[3], _ $aSysTime[4],$aSysTime[5],$aSysTime[6],$aSysTime[7],$iFormat,$iPrecision,$bAMPMConversion) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeFormat($iLocalFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts Local FileTime to a *Local* SystemTime formatted value. ; Returns either an array, a formatted string, or a 3-element array of formatted strings ; ; $iLocalFileTime = 64-bit *Local* FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: Converted/Formatted Array, String, or Array-of-Strings ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeFormat($iLocalFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ;~ If $iLocalFileTime<0 Then Return SetError(1,0,"") ; checked in below call ; Convert file time to a system time array & return result Local $aSysTime=_WinTime_LocalFileTimeToSystemTime($iLocalFileTime) If @error Then Return SetError(@error,@extended,"") ; Return only the SystemTime array? If $iFormat=0 Then Return $aSysTime Local $vReturn=_WinTime_FormatTime($aSysTime[0],$aSysTime[1],$aSysTime[2],$aSysTime[3], _ $aSysTime[4],$aSysTime[5],$aSysTime[6],$aSysTime[7],$iFormat,$iPrecision,$bAMPMConversion) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_LocalFileTimeFormatBasic($iLocalFileTime,$iFormat=0) ; ; 'Basic' version of above function (used to cut down on size/speed where needed): ; Converts Local FileTime to a *Local* SystemTime formatted value, returning 1 of 2 formats: ; - an array, or ; - a string in 'YYYYMMDDHHMMSS' format ; ; $iLocalFileTime = 64-bit *Local* FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1: Main String's format: YYYYMMDDHHMMSS ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; ; Returns: ; Success: Converted/Formatted Array or String, with @error = 0 ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_LocalFileTimeFormatBasic($iLocalFileTime,$iFormat=0) ;~ If $iLocalFileTime<0 Then Return SetError(1,0,"") ; checked in below call ; Convert file time to a system time array & return result Local $aSysTime=_WinTime_LocalFileTimeToSystemTime($iLocalFileTime) If @error Then Return SetError(@error,@extended,"") ; Return only the SystemTime array? If $iFormat=0 Then Return $aSysTime ; No - return 'YYYYMMDDHHMMSS' string format: Return $aSysTime[0]&StringRight(0&$aSysTime[1],2)&StringRight(0&$aSysTime[2],2)&StringRight(0&$aSysTime[3],2)&StringRight(0&$aSysTime[4],2)&StringRight(0&$aSysTime[5],2) ; This is 'nicer' but slower than the above: ;~ Return $aSysTime[0]&StringFormat("%02u%02u%02u%02u%02u",$aSysTime[1],$aSysTime[2],$aSysTime[3],$aSysTime[4],$aSysTime[5]) EndFunc ; =============================================================================================================================== ; Func _WinTime_UTCFileTimeFormat($iUTCFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ; ; Converts UTC FileTime to a formatted *Local* SystemTime value ; Returns either an array, a formatted string, or a 3-element array of formatted strings ; ; NOTE: When used with _WinAPI_FileFind.. functions, the *PREFERRED* METHOD of calling this is: ; _WinAPI_FileFindTimeConvert() ; ; $iUTCFileTime = 64-bit UTC FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1 or 16: Main String's format: YYYYMMDDHHMM[SS[MSMSMSMS]] ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; 2 Main String's format [style /, :]: MM/DD/YYYY HH:MM[:SS[:MSMSMSMS]] ; 3 Main String's format [style /, : alternate]: DD/MM/YYYY HH:MM[:SS[:MSMSMSMS]] ; 4 Main String's format [style Month DD,YYYY]: "Month" DD,YYYY HH:MM[:SS[:MSMSMSMS]] ; 5 Main String's format [style DD Month YYYY]: DD "Month" YYYY HH:MM[:SS[:MSMSMSMS]] ; +8 = Prefix string with "DayOfWeek, " ; +16 = Return array which includes the Main String (formatted) + Month + DayOfWeek strings ; [0]=Main String as formatted in #1-5 (+ optional +8) ; [1]=Month ("January"-"December") ; [2]=DayOfWeek ("Sunday"-"Saturday") ; $iPrecision = extra precision of return: 0 = Minutes, 1=Minutes+Seconds,>1=Minutes+Seconds+Milliseconds ; $bAMPMConversion = convert to AM/PM format clock, and affix AM/PM to end of string ; ; Returns: ; Success: Converted/Formatted Array, String, or Array-of-Strings ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_UTCFileTimeFormat($iUTCFileTime,$iFormat=4,$iPrecision=0,$bAMPMConversion=False) ;~ If $iUTCFileTime<0 Then Return SetError(1,0,"") ; checked in below call ; First convert file time (UTC-based file time) to 'local file time' Local $iLocalFileTime=_WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If @error Then Return SetError(@error,@extended,"") ; Rare occassion: a filetime near the origin (January 1, 1601!!) is used, ; causing a negative result (for some timezones). Return as invalid param. If $iLocalFileTime<0 Then Return SetError(1,0,"") ; Then convert file time to a system time array & format & return it Local $vReturn=_WinTime_LocalFileTimeFormat($iLocalFileTime,$iFormat,$iPrecision,$bAMPMConversion) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_UTCFileTimeFormatBasic($iUTCFileTime,$iFormat=0) ; ; 'Basic' version of above function (used to cut down on size/speed where needed): ; Converts UTC FileTime to a *Local* SystemTime formatted value, returning 1 of 2 formats: ; - an array, or ; - a string in 'YYYYMMDDHHMMSS' format ; ; $iUTCFileTime = 64-bit UTC FileTime value to convert to formatted *Local* SystemTime ; $iFormat = Format to return in. string/array of strings/array of numbers ; 0 (Array-of-Numbers) format [this returns what is passed to it, for the purpose of _WinTime_LocalFileTimeFormat() call]: ; [0] = Year (1601 - 30,828) ; [1] = Month (1-12) ; [2] = Day (1-31) [Day-Of-The-Week is at [7]] ; [3] = Hour (0-23) ; [4] = Minute (0-59) ; [5] = Seconds (0-59) ; [6] = Milliseconds (0-999) ; [7] = Day-Of-The-Week (0-6, Sunday - Saturday) ; 1: Main String's format: YYYYMMDDHHMMSS ; [technically Year can be 5 chars - but that's a good 7900+ years from now] ; ; Returns: ; Success: Converted/Formatted Array or String & @error=0 ; Failure: "", with @error set: ; @error = 1 = invalid parameter ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; @error = 3 = API function returned 'Fail'/False. GetLastError will have more info ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_UTCFileTimeFormatBasic($iUTCFileTime,$iFormat=0) ; First convert file time (UTC-based file time) to 'local file time' Local $vReturn,$iLocalFileTime=_WinTime_UTCFileTimeToLocalFileTime($iUTCFileTime) If @error Then Return SetError(@error,@extended,"") ; Rare occassion: a filetime near the origin (January 1, 1601!!) is used, ; causing a negative result (for some timezones). Return as invalid param. If $iLocalFileTime<0 Then Return SetError(1,0,"") ; Then convert file time to a system time array & format & return it $vReturn=_WinTime_LocalFileTimeFormatBasic($iLocalFileTime,$iFormat) Return SetError(@error,@extended,$vReturn) EndFunc ; =============================================================================================================================== ; Func _WinTime_AddToFileTime($iFileTime,$iDay=0,$iHour=0,$iMin=0,$iSec=0,$iMilSec=0,$iNanoSec=0) ; ; Function to add/subtract time/days to a FileTime value, with restrictions. ; (Months & Years are not allowed as parameters because of the calculations and needed knowledge about ; both leap year and the month that the FileTime represents, and what the calculation will pass by) ; ; $iFileTime = 64bit FileTime, either UTC or Local, to add/subtract to ; $iDay = # of days to add/subtract (using positive or negative #'s) ; $iHour = # of hours "" "" ; $iMin = # of minutes "" "" ; $iSec = # of seconds "" "" ; $iMilSec = # of milliseconds "" "" ; $iNanoSec = # of nanoseconds "" "" - NOTE: this will be divided by 100, as 100-nsecond intervals are the smallest allowable #s ; ; * FOR WEEKS * : in $iDay, add (#OfWeeks * 7) to rest of equation ; ; NOTES Regaring Limitations: ; Year is *NOT* easily added without taking into account leap years. To calculate such values, ; the FileTime must be converted to UTC SystemTime, then a calculation would need to be done to ; figure out if there is/will-be leap year(s). Then the leap years would be 366, non = 365. ; Ideally it would be ($iYear*365*24*60*60*10000000), but thats not taking into accout 366-day leap years ; ; ALSO, Month is *NOT* easily figured out without knowing which month you are currently on, how many ; days in each month to add, whether there is or will be leap year(s) , and so on. ; Ideally it would be something like ($iMonth*30*24*60*60*10000000), but non-30 day months and extra-day leap-years are ignored ; ; For those needs, read into the _DateAdd() UDF ; ; Additional NOTE Regarding Nanoseconds: ; These can be added (and will be divided by 100 as explained above), but will *only* have a *noticeable* effect if ; the add/subtract causes a rollover to occur in Milliseconds. ; Reason: when converted to SystemTime, the highest precision reported is Milliseconds ; ; Returns: ; Success: New modified 64-bit FileTime ; Failure: -1, with @error set to 1 (invalid parameter) ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_AddToFileTime($iFileTime,$iDay,$iHour=0,$iMin=0,$iSec=0,$iMilSec=0,$iNanoSec=0) If $iFileTime<0 Then return SetError(1,0,-1) ; Less calculations way: Return $iFileTime+($iDay*864000000000)+($iHour*36000000000)+($iMin*600000000)+($iSec*10000000)+($iMilSec*10000)+Round($iNanoSec/100) ; More readable\understandable way: ;Return $iFileTime+($iDay*24*60*60*10000000)+($iHour*60*60*10000000)+($iMin*60*10000000)+($iSec*10000000)+ _ ; ($iMilSec*10000)+Round($iNanoSec/100) EndFunc ; =============================================================================================================================== ; Func _WinTime_IsLeapYear($iYear) ; ; Simple calculation based on numerical input (Year) to determine if it is a leap year (366 day year (29 days in February)) ; ; $iYear = year to check ; ; Returns: ; Success: True/False, with @error = 0. (True = IS leap year, False = is NOT) ; Failure: False with @error = 1 (invalid param) ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_IsLeapYear($iYear) If $iYear<0 Then Return SetError(1,1,False) ; Divisible by 4 and not evenly divisible by 100: GOOD If BitAND($iYear,3)=0 And Mod($iYear,100) Then Return True ; Evenly divisible by 400? (which also implies evenly divisible by 100, and 4), also good. If Mod($iYear,400)=0 Then Return True ; None of the above (either not divisible by 4, or divisible by 100 and not by 400. [or not a number]) Return False EndFunc #region WINTIME_RETIRED_FUNCTIONS #cs ; - RETIRED FUNCTION - ; =============================================================================================================================== ; Func _WinTime_CompareFileTime($iTimeA,$iTimeB) ; ; Function to compare two 64bit FileTime values. This allows <, =, and > returns. ; ; NOTE: This can be done using basic 64bit compares, so the point of this function is moot. ; ; $iTimeA = 1st 64bit FileTime value ; $iTimeB = 2nd 64bit FileTime value ; ; Return: ; Success: -1,0,or 1: ; -1 means $iTimeA < $iTimeB ($iTimeA is *earlier* than $iTimeB) ; 0 means $iTimeA == $iTimeB ($iTimeA is *EQUAL* to $iTimeB) ; 1 means $iTimeA > $iTimeB ($iTimeA is *later* than $iTimeB) ; Failure: 0, with @error set: ; @error = 2 = DLL Call error, @extended = actual DLLCall error code ; ; Author: Ascend4nt ; =============================================================================================================================== Func _WinTime_CompareFileTime($iTimeA,$iTimeB) Local $aRet=DllCall($_COMMON_KERNEL32DLL,"long","CompareFileTime","uint64*",$iTimeA,"uint64*",$iTimeB) If @error Then Return SetError(2,@error,0) Return $aRet[0] EndFunc ; - END RETIRED FUNCTION - #ce #endregion I have tried previous version 1.0.0.4 but has a severe bug: it uses NtCreateKey instead of NtOpenKey and that leads to infinte key being created, this breaks registry. However recursion is working in previous version in Windows 10. Please help me to bring this back to life for modern OS. Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 28, 2022 Author Share Posted November 28, 2022 Cannot fix the typos: the code was released by joakim in 2012, not 2014. Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 Sorry for extra code, I cannot edit opening post. Only first code is relevant, the second two parts are a copy of it. Also code won't compile because some error in line 618 stating some entity is not declared correctly (no further explanation from AutoIt, I even tried compiling with other version 3.3.8 that was actual version at the time of release of version 1.0.0.5 of SetRegTime, no luck). Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
Nine Posted November 29, 2022 Share Posted November 29, 2022 Part of programming is the extra fun part of debugging. So do not give us the whole code of yours for us to debug it for you. Either you put effort of doing it yourself, or hire someone to do it for you. tinygoblin 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 While I'm having trouble with compiling open source code, this is not my code to begin with and I have no idea why same thing can work in 7 and it stops working in 10: same functions, same methods. My only guess is maybe it should use RegOpenKey instead of NtOpenKey since ntdll.dll access may have gained some restrictions in Windows 10 (no documentation on that). As it goes to debugging I provided two problem points I can't deal with: 1) one is related on legacy AutoIt functions by Ascend4nt _WinTimeFunctions.au3 (won't allow compiling because of wrong declaration in line 618), 2) another one being something off in _CheckSubKeys function in lines 306-395 that is specific to Windows 10. I may be not asking correctly (inability to edit post helps a lot) but you're completely wrong I didn't look into it before asking. I'm not being rude to anyone so I presume advising to hire somebody somewhere for open source non-commercial question is not a reasonable participation to this thread. Thanks for taking time to respond though. Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 I believe the code of SetRegTime.au3 provided at GitHub may be outdated and contain some error so I extracted if from a working SetRegTime 1.0.0.5 exe file (since it's an open source software it's not a violation), but that doesn't help for Windows 10 and it won't work as EXE for some reason (no errors in syntax check and Go works in AutoIt Editor) expandcollapse popup#Region #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Res_Comment=Set LastWriteTime of keys in registry #AutoIt3Wrapper_Res_Description=Manipulate timestamps in the registry #AutoIt3Wrapper_Res_Fileversion=1.0.0.5 #AutoIt3Wrapper_Res_LegalCopyright=Joakim Schicht #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion Global $_common_kernel32dll = DllOpen("kernel32.dll") Func _wintime_getsystemtimeaslocalfiletime() Local $aret = DllCall($_common_kernel32dll, "none", "GetSystemTimeAsFileTime", "uint64*", 0) If @error Then Return SetError(2, @error, -1) Return $aret[1] EndFunc Func _wintime_utcfiletimetolocalfiletime($iutcfiletime) If $iutcfiletime < 0 Then Return SetError(1, 0, -1) Local $aret = DllCall($_common_kernel32dll, "bool", "FileTimeToLocalFileTime", "uint64*", $iutcfiletime, "uint64*", 0) If @error Then Return SetError(2, @error, -1) If NOT $aret[0] Then Return SetError(3, 0, -1) Return $aret[2] EndFunc Func _wintime_getutctolocalfiletimedelta() Local $iutcfiletime = 864000000000 $ilocalfiletime = _wintime_utcfiletimetolocalfiletime($iutcfiletime) If @error Then Return SetError(@error, @extended, -1) Return $ilocalfiletime - $iutcfiletime EndFunc Func _wintime_getlocaltoutcfiletimedelta() Local $idelta = _wintime_getutctolocalfiletimedelta() If @error Then Return SetError(@error, @extended, -1) Return -$idelta EndFunc Func _wintime_localfiletimetoutcfiletime($ilocalfiletime) If $ilocalfiletime < 0 Then Return SetError(1, 0, -1) Local $aret = DllCall($_common_kernel32dll, "bool", "LocalFileTimeToFileTime", "uint64*", $ilocalfiletime, "uint64*", 0) If @error Then Return SetError(2, @error, -1) If NOT $aret[0] Then Return SetError(3, 0, -1) Return $aret[2] EndFunc Func _wintime_localfiletimetosystemtime($ilocalfiletime) Local $aret, $stsystime, $asystime[8] = [-1, -1, -1, -1, -1, -1, -1, -1] If $ilocalfiletime < 0 Then Return SetError(1, 0, $asystime) $stsystime = DllStructCreate("ushort[8]") $aret = DllCall($_common_kernel32dll, "bool", "FileTimeToSystemTime", "uint64*", $ilocalfiletime, "ptr", DllStructGetPtr($stsystime)) If @error Then Return SetError(2, @error, $asystime) If NOT $aret[0] Then Return SetError(3, 0, $asystime) Dim $asystime[8] = [DllStructGetData($stsystime, 1, 1), DllStructGetData($stsystime, 1, 2), DllStructGetData($stsystime, 1, 4), DllStructGetData($stsystime, 1, 5), DllStructGetData($stsystime, 1, 6), DllStructGetData($stsystime, 1, 7), DllStructGetData($stsystime, 1, 8), DllStructGetData($stsystime, 1, 3)] Return $asystime EndFunc Func _wintime_systemtimetolocalfiletime($iyear, $imonth, $iday, $ihour, $imin, $isec, $imilsec, $idayofweek = -1) If $iyear < 1601 OR $iyear > 30827 Then Return SetError(1, 0, -1) Local $stsystime = DllStructCreate("ushort[8]") DllStructSetData($stsystime, 1, $iyear, 1) DllStructSetData($stsystime, 1, $imonth, 2) DllStructSetData($stsystime, 1, $idayofweek, 3) DllStructSetData($stsystime, 1, $iday, 4) DllStructSetData($stsystime, 1, $ihour, 5) DllStructSetData($stsystime, 1, $imin, 6) DllStructSetData($stsystime, 1, $isec, 7) DllStructSetData($stsystime, 1, $imilsec, 8) Local $aret = DllCall($_common_kernel32dll, "bool", "SystemTimeToFileTime", "ptr", DllStructGetPtr($stsystime), "int64*", 0) If @error Then Return SetError(2, @error, -1) If NOT $aret[0] Then Return SetError(3, 0, -1) Return $aret[2] EndFunc Func _wintime_formattime($iyear, $imonth, $iday, $ihour, $imin, $isec, $imilsec, $idayofweek, $iformat = 4, $iprecision = 0, $bampmconversion = False) Local Static $_wt_amonths[12] = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] Local Static $_wt_adays[7] = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] If NOT $iformat OR $imonth < 1 OR $imonth > 12 OR $idayofweek > 6 Then Return SetError(1, 0, "") Local $smm = StringRight(0 & $imonth, 2), $sdd = StringRight(0 & $iday, 2), $smin = StringRight(0 & $imin, 2) Local $shh, $sss, $sms, $sampm If $iprecision Then $sss = StringRight(0 & $isec, 2) If $iprecision > 1 Then $sms = StringRight("000" & $imilsec, 3) Else $sms = "" EndIf Else $sss = "" $sms = "" EndIf If $bampmconversion Then If $ihour > 11 Then $sampm = " PM" If $ihour = 12 Then $shh = "12" Else $shh = StringRight(0 & ($ihour - 12), 2) EndIf Else $sampm = " AM" If $ihour Then $shh = StringRight(0 & $ihour, 2) Else $shh = "12" EndIf EndIf Else $sampm = "" $shh = StringRight(0 & $ihour, 2) EndIf Local $sdatetimestr, $areturnarray[3] If BitAND($iformat, 16) Then $areturnarray[1] = $_wt_amonths[$imonth - 1] If $idayofweek >= 0 Then $areturnarray[2] = $_wt_adays[$idayofweek] Else $areturnarray[2] = "" EndIf $iformat = BitAND($iformat, 15) Else $areturnarray[1] = "" EndIf If BitAND($iformat, 8) Then If $idayofweek < 0 Then Return SetError(1, 0, "") $sdatetimestr = $_wt_adays[$idayofweek] & ", " $iformat = BitAND($iformat, 7) Else $sdatetimestr = "" EndIf If $iformat < 2 Then $sdatetimestr &= $iyear & $smm & $sdd & $shh & $smin & $sss & $sms & $sampm Else Switch $iformat Case 2 $sdatetimestr &= $smm & "/" & $sdd & "/" Case 3 $sdatetimestr &= $sdd & "/" & $smm & "/" Case 4 $sdatetimestr &= $_wt_amonths[$imonth - 1] & " " & $sdd & ", " Case 5 $sdatetimestr &= $sdd & " " & $_wt_amonths[$imonth - 1] & " " Case 6 $sdatetimestr &= $iyear & "-" & $smm & "-" & $sdd $iyear = "" Case Else Return SetError(1, 0, "") EndSwitch $sdatetimestr &= $iyear & " " & $shh & ":" & $smin If $iprecision Then $sdatetimestr &= ":" & $sss If $iprecision > 1 Then $sdatetimestr &= ":" & $sms EndIf $sdatetimestr &= $sampm EndIf If $areturnarray[1] <> "" Then $areturnarray[0] = $sdatetimestr Return $areturnarray EndIf Return $sdatetimestr EndFunc Func _wintime_formatsystimearray(ByRef $asystime, $iformat = 4, $iprecision = 0, $bampmconversion = False) If NOT IsArray($asystime) Then Return SetError(1, 0, "") If $asystime[0] = -1 Then Return SetError(1, 0, "") If NOT $iformat Then Return $asystime Local $vreturn = _wintime_formattime($asystime[0], $asystime[1], $asystime[2], $asystime[3], $asystime[4], $asystime[5], $asystime[6], $asystime[7], $iformat, $iprecision, $bampmconversion) Return SetError(@error, @extended, $vreturn) EndFunc Func _wintime_localfiletimeformat($ilocalfiletime, $iformat = 4, $iprecision = 0, $bampmconversion = False) Local $asystime = _wintime_localfiletimetosystemtime($ilocalfiletime) If @error Then Return SetError(@error, @extended, "") If $iformat = 0 Then Return $asystime Local $vreturn = _wintime_formattime($asystime[0], $asystime[1], $asystime[2], $asystime[3], $asystime[4], $asystime[5], $asystime[6], $asystime[7], $iformat, $iprecision, $bampmconversion) Return SetError(@error, @extended, $vreturn) EndFunc Func _wintime_localfiletimeformatbasic($ilocalfiletime, $iformat = 0) Local $asystime = _wintime_localfiletimetosystemtime($ilocalfiletime) If @error Then Return SetError(@error, @extended, "") If $iformat = 0 Then Return $asystime Return $asystime[0] & StringRight(0 & $asystime[1], 2) & StringRight(0 & $asystime[2], 2) & StringRight(0 & $asystime[3], 2) & StringRight(0 & $asystime[4], 2) & StringRight(0 & $asystime[5], 2) EndFunc Func _wintime_utcfiletimeformat($iutcfiletime, $iformat = 4, $iprecision = 0, $bampmconversion = False) Local $ilocalfiletime = _wintime_utcfiletimetolocalfiletime($iutcfiletime) If @error Then Return SetError(@error, @extended, "") If $ilocalfiletime < 0 Then Return SetError(1, 0, "") Local $vreturn = _wintime_localfiletimeformat($ilocalfiletime, $iformat, $iprecision, $bampmconversion) Return SetError(@error, @extended, $vreturn) EndFunc Func _wintime_utcfiletimeformatbasic($iutcfiletime, $iformat = 0) Local $vreturn, $ilocalfiletime = _wintime_utcfiletimetolocalfiletime($iutcfiletime) If @error Then Return SetError(@error, @extended, "") If $ilocalfiletime < 0 Then Return SetError(1, 0, "") $vreturn = _wintime_localfiletimeformatbasic($ilocalfiletime, $iformat) Return SetError(@error, @extended, $vreturn) EndFunc Func _wintime_addtofiletime($ifiletime, $iday, $ihour = 0, $imin = 0, $isec = 0, $imilsec = 0, $inanosec = 0) If $ifiletime < 0 Then Return SetError(1, 0, -1) Return $ifiletime + ($iday * 864000000000) + ($ihour * 36000000000) + ($imin * 600000000) + ($isec * 10000000) + ($imilsec * 10000) + Round($inanosec / 100) EndFunc Func _wintime_isleapyear($iyear) If $iyear < 0 Then Return SetError(1, 1, False) If BitAND($iyear, 3) = 0 AND Mod($iyear, 100) Then Return True If Mod($iyear, 400) = 0 Then Return True Return False EndFunc #Region WINTIME_RETIRED_FUNCTIONS #EndRegion Func _hextostring($strhex) If StringLeft($strhex, 2) = "0x" Then Return BinaryToString($strhex) Return BinaryToString("0x" & $strhex) EndFunc Func _stringbetween($s_string, $s_start, $s_end, $v_case = -1) Local $s_case = "" If $v_case = Default OR $v_case = -1 Then $s_case = "(?i)" Local $s_pattern_escape = "(\.|\||\*|\?|\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)" $s_start = StringRegExpReplace($s_start, $s_pattern_escape, "\\$1") $s_end = StringRegExpReplace($s_end, $s_pattern_escape, "\\$1") If $s_start = "" Then $s_start = "\A" If $s_end = "" Then $s_end = "\z" Local $a_ret = StringRegExp($s_string, "(?s)" & $s_case & $s_start & "(.*?)" & $s_end, 3) If @error Then Return SetError(1, 0, 0) Return $a_ret EndFunc Func _stringencrypt($i_encrypt, $s_encrypttext, $s_encryptpassword, $i_encryptlevel = 1) If $i_encrypt <> 0 AND $i_encrypt <> 1 Then SetError(1, 0, "") ElseIf $s_encrypttext = "" OR $s_encryptpassword = "" Then SetError(1, 0, "") Else If Number($i_encryptlevel) <= 0 OR Int($i_encryptlevel) <> $i_encryptlevel Then $i_encryptlevel = 1 Local $v_encryptmodified Local $i_encryptcounth Local $i_encryptcountg Local $v_encryptswap Local $av_encryptbox[256][2] Local $i_encryptcounta Local $i_encryptcountb Local $i_encryptcountc Local $i_encryptcountd Local $i_encryptcounte Local $v_encryptcipher Local $v_encryptcipherby If $i_encrypt = 1 Then For $i_encryptcountf = 0 To $i_encryptlevel Step 1 $i_encryptcountg = "" $i_encryptcounth = "" $v_encryptmodified = "" For $i_encryptcountg = 1 To StringLen($s_encrypttext) If $i_encryptcounth = StringLen($s_encryptpassword) Then $i_encryptcounth = 1 Else $i_encryptcounth += 1 EndIf $v_encryptmodified = $v_encryptmodified & Chr(BitXOR(Asc(StringMid($s_encrypttext, $i_encryptcountg, 1)), Asc(StringMid($s_encryptpassword, $i_encryptcounth, 1)), 255)) Next $s_encrypttext = $v_encryptmodified $i_encryptcounta = "" $i_encryptcountb = 0 $i_encryptcountc = "" $i_encryptcountd = "" $i_encryptcounte = "" $v_encryptcipherby = "" $v_encryptcipher = "" $v_encryptswap = "" $av_encryptbox = "" Local $av_encryptbox[256][2] For $i_encryptcounta = 0 To 255 $av_encryptbox[$i_encryptcounta][1] = Asc(StringMid($s_encryptpassword, Mod($i_encryptcounta, StringLen($s_encryptpassword)) + 1, 1)) $av_encryptbox[$i_encryptcounta][0] = $i_encryptcounta Next For $i_encryptcounta = 0 To 255 $i_encryptcountb = Mod(($i_encryptcountb + $av_encryptbox[$i_encryptcounta][0] + $av_encryptbox[$i_encryptcounta][1]), 256) $v_encryptswap = $av_encryptbox[$i_encryptcounta][0] $av_encryptbox[$i_encryptcounta][0] = $av_encryptbox[$i_encryptcountb][0] $av_encryptbox[$i_encryptcountb][0] = $v_encryptswap Next For $i_encryptcounta = 1 To StringLen($s_encrypttext) $i_encryptcountc = Mod(($i_encryptcountc + 1), 256) $i_encryptcountd = Mod(($i_encryptcountd + $av_encryptbox[$i_encryptcountc][0]), 256) $i_encryptcounte = $av_encryptbox[Mod(($av_encryptbox[$i_encryptcountc][0] + $av_encryptbox[$i_encryptcountd][0]), 256)][0] $v_encryptcipherby = BitXOR(Asc(StringMid($s_encrypttext, $i_encryptcounta, 1)), $i_encryptcounte) $v_encryptcipher &= Hex($v_encryptcipherby, 2) Next $s_encrypttext = $v_encryptcipher Next Else For $i_encryptcountf = 0 To $i_encryptlevel Step 1 $i_encryptcountb = 0 $i_encryptcountc = "" $i_encryptcountd = "" $i_encryptcounte = "" $v_encryptcipherby = "" $v_encryptcipher = "" $v_encryptswap = "" $av_encryptbox = "" Local $av_encryptbox[256][2] For $i_encryptcounta = 0 To 255 $av_encryptbox[$i_encryptcounta][1] = Asc(StringMid($s_encryptpassword, Mod($i_encryptcounta, StringLen($s_encryptpassword)) + 1, 1)) $av_encryptbox[$i_encryptcounta][0] = $i_encryptcounta Next For $i_encryptcounta = 0 To 255 $i_encryptcountb = Mod(($i_encryptcountb + $av_encryptbox[$i_encryptcounta][0] + $av_encryptbox[$i_encryptcounta][1]), 256) $v_encryptswap = $av_encryptbox[$i_encryptcounta][0] $av_encryptbox[$i_encryptcounta][0] = $av_encryptbox[$i_encryptcountb][0] $av_encryptbox[$i_encryptcountb][0] = $v_encryptswap Next For $i_encryptcounta = 1 To StringLen($s_encrypttext) Step 2 $i_encryptcountc = Mod(($i_encryptcountc + 1), 256) $i_encryptcountd = Mod(($i_encryptcountd + $av_encryptbox[$i_encryptcountc][0]), 256) $i_encryptcounte = $av_encryptbox[Mod(($av_encryptbox[$i_encryptcountc][0] + $av_encryptbox[$i_encryptcountd][0]), 256)][0] $v_encryptcipherby = BitXOR(Dec(StringMid($s_encrypttext, $i_encryptcounta, 2)), $i_encryptcounte) $v_encryptcipher = $v_encryptcipher & Chr($v_encryptcipherby) Next $s_encrypttext = $v_encryptcipher $i_encryptcountg = "" $i_encryptcounth = "" $v_encryptmodified = "" For $i_encryptcountg = 1 To StringLen($s_encrypttext) If $i_encryptcounth = StringLen($s_encryptpassword) Then $i_encryptcounth = 1 Else $i_encryptcounth += 1 EndIf $v_encryptmodified &= Chr(BitXOR(Asc(StringMid($s_encrypttext, $i_encryptcountg, 1)), Asc(StringMid($s_encryptpassword, $i_encryptcounth, 1)), 255)) Next $s_encrypttext = $v_encryptmodified Next EndIf Return $s_encrypttext EndIf EndFunc Func _stringexplode($sstring, $sdelimiter, $ilimit = 0) If $ilimit > 0 Then $sstring = StringReplace($sstring, $sdelimiter, Chr(0), $ilimit) $sdelimiter = Chr(0) ElseIf $ilimit < 0 Then Local $iindex = StringInStr($sstring, $sdelimiter, 0, $ilimit) If $iindex Then $sstring = StringLeft($sstring, $iindex - 1) EndIf EndIf Return StringSplit($sstring, $sdelimiter, 3) EndFunc Func _stringinsert($s_string, $s_insertstring, $i_position) Local $i_length, $s_start, $s_end If $s_string = "" OR (NOT IsString($s_string)) Then Return SetError(1, 0, $s_string) ElseIf $s_insertstring = "" OR (NOT IsString($s_string)) Then Return SetError(2, 0, $s_string) Else $i_length = StringLen($s_string) If (Abs($i_position) > $i_length) OR (NOT IsInt($i_position)) Then Return SetError(3, 0, $s_string) EndIf EndIf If $i_position = 0 Then Return $s_insertstring & $s_string ElseIf $i_position > 0 Then $s_start = StringLeft($s_string, $i_position) $s_end = StringRight($s_string, $i_length - $i_position) Return $s_start & $s_insertstring & $s_end ElseIf $i_position < 0 Then $s_start = StringLeft($s_string, Abs($i_length + $i_position)) $s_end = StringRight($s_string, Abs($i_position)) Return $s_start & $s_insertstring & $s_end EndIf EndFunc Func _stringproper($s_string) Local $ix = 0 Local $capnext = 1 Local $s_nstr = "" Local $s_curchar For $ix = 1 To StringLen($s_string) $s_curchar = StringMid($s_string, $ix, 1) Select Case $capnext = 1 If StringRegExp($s_curchar, "[a-zA-ZÀ-ÿšœžŸ]") Then $s_curchar = StringUpper($s_curchar) $capnext = 0 EndIf Case NOT StringRegExp($s_curchar, "[a-zA-ZÀ-ÿšœžŸ]") $capnext = 1 Case Else $s_curchar = StringLower($s_curchar) EndSelect $s_nstr &= $s_curchar Next Return $s_nstr EndFunc Func _stringrepeat($sstring, $irepeatcount) Local $sresult Select Case NOT StringIsInt($irepeatcount) SetError(1) Return "" Case StringLen($sstring) < 1 SetError(1) Return "" Case $irepeatcount <= 0 SetError(1) Return "" Case Else For $icount = 1 To $irepeatcount $sresult &= $sstring Next Return $sresult EndSelect EndFunc Func _stringreverse($s_string) Local $i_len = StringLen($s_string) If $i_len < 1 Then Return SetError(1, 0, "") Local $t_chars = DllStructCreate("char[" & $i_len + 1 & "]") DllStructSetData($t_chars, 1, $s_string) Local $a_rev = DllCall("msvcrt.dll", "ptr:cdecl", "_strrev", "struct*", $t_chars) If @error OR $a_rev[0] = 0 Then Return SetError(2, 0, "") Return DllStructGetData($t_chars, 1) EndFunc Func _stringtohex($strchar) Return Hex(StringToBinary($strchar)) EndFunc Global Const $__winapiconstant_format_message_allocate_buffer = 256 Global Const $__winapiconstant_format_message_from_system = 4096 Global $datetimeformat = 6 Global Const $tagiostatusblock = "dword Status;ptr Information" Global Const $tagobjectattributes = "ulong Length;hwnd RootDirectory;ptr ObjectName;ulong Attributes;ptr SecurityDescriptor;ptr SecurityQualityOfService" Global Const $tagunicodestring = "ushort Length;ushort MaximumLength;ptr Buffer" Global Const $tagkeywritetimeinformation = "int64 LastWriteTime" Global Const $tagkeybasicinformation = "int64 LastWriteTime;ulong TitleIndex;ulong NameLength;wchar Name[400]" Global Const $keybasicinformation = 0 Global Const $obj_case_insensitive = 64 Global Const $key_read = 131097 Global Const $key_write = 131078 Global Const $key_create_link = 32 Global Const $key_all_access = 983103 Global Const $key_create_sub_key = 4 Global Const $key_enumerate_sub_keys = 8 Global Const $key_notify = 16 Global Const $key_query_value = 1 Global Const $reg_option_non_volatile = 0 Global Const $keywritetimeinformation = 0 Global Const $tagkeynodeinformation = "int64 LastWriteTime;ulong TitleIndex;ulong ClassOffset;ulong ClassLength;ulong NameLength;byte Name[2048]" Global Const $keynodeinformation = 1 Global $tdelta = _wintime_getutctolocalfiletimedelta() Global $rootdir, $objname Global $timerstart = TimerInit() ConsoleWrite("Starting SetRegTime by Joakim Schicht" & @CRLF) ConsoleWrite("Version 1.0.0.5" & @CRLF) ConsoleWrite("" & @CRLF) Global $hntdll = DllOpen("ntdll.dll") _validate_parameters() ConsoleWrite("Your current local time (timezone and/or daylight saving) is " & $tdelta / 36000000000 & " hours off UTC" & @CRLF) If $cmdline[0] = 1 Then If StringRight($cmdline[1], 1) = "\" Then $rootdir = StringTrimRight($cmdline[1], 1) Else $rootdir = $cmdline[1] EndIf $objectnames = StringSplit($rootdir, "\") Local $tmp For $i = 1 To UBound($objectnames) - 2 $tmp &= $objectnames[$i] & "\" Next $rootdir = StringTrimRight($tmp, 1) If $objectnames[0] < 2 Then $objname = "" Else $objname = $objectnames[UBound($objectnames) - 1] EndIf $querykey = _ntquerykey($rootdir, $objname, BitOR($key_query_value, $key_enumerate_sub_keys)) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($querykey, 8) & @CRLF) Exit Else ConsoleWrite("The key: " & $querykey[0] & " has LastWriteTime timestamp: " & $querykey[1] & @CRLF) Exit EndIf EndIf $formattedtimestamp = _configtimestamp() If $formattedtimestamp = -1 Then ConsoleWrite("Error: Timestamp generation failed" & @CRLF) Exit EndIf Global $newtimestamp = StringMid($formattedtimestamp[0], 1, 14) & $formattedtimestamp[8] ConsoleWrite("Generated timestamp: " & $newtimestamp & " (" & $cmdline[2] & ")" & @CRLF) If $cmdline[3] = "-n" Then $regkey = $cmdline[1] $hkey = _ntopenkey($regkey, BitOR($key_write, $key_read)) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($hkey, 8) & @CRLF) Exit EndIf $settimestamp = _ntsetinformationkey($hkey, $keywritetimeinformation, $newtimestamp) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($settimestamp, 8) & @CRLF) Exit EndIf $flushkey = _ntflushkey($hkey) If @error Then ConsoleWrite("Ntstatus: 0x" & Hex($flushkey, 8) & @CRLF) Exit EndIf ConsoleWrite("Successfully modified LastWriteTime on the key: " & $cmdline[1] & @CRLF) Exit ElseIf $cmdline[3] = "-s" Then If StringRight($cmdline[1], 1) = "\" Then $rootdir = StringTrimRight($cmdline[1], 1) Else $rootdir = $cmdline[1] EndIf $objectnames = StringSplit($rootdir, "\") Local $tmp For $i = 1 To UBound($objectnames) - 2 $tmp &= $objectnames[$i] & "\" Next $rootdir = StringTrimRight($tmp, 1) If $objectnames[0] < 2 Then $objname = "" Else $objname = $objectnames[UBound($objectnames) - 1] EndIf _checksubkeys($rootdir, $objname) EndIf _end($timerstart) DllClose($hntdll) Exit Func _ntsetinformationkey($handle, $key_set_information_class, $timestamp) Local $skwti = DllStructCreate($tagkeywritetimeinformation) DllStructSetData($skwti, "LastWriteTime", $timestamp) Local $ret = DllCall($hntdll, "int", "NtSetInformationKey", "hwnd", $handle, "dword", $key_set_information_class, "ptr", DllStructGetPtr($skwti), "dword", DllStructGetSize($skwti)) If NOT nt_success($ret[0]) Then ConsoleWrite("Error in NtSetInformationKey : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) Return SetError(1, 0, $ret[0]) EndIf EndFunc Func _ntflushkey($keyhandle) Local $ret = DllCall($hntdll, "int", "NtFlushKey", "hwnd", $keyhandle) If NOT nt_success($ret[0]) Then ConsoleWrite("Error in NtFlushKey" & @CRLF) Return SetError(1, 0, $ret[0]) EndIf EndFunc Func _ntopenkey($regkey, $desiredaccess) Local $disposition, $ret, $keyhandle Local $szname = DllStructCreate("wchar[260]") Local $sus = DllStructCreate($tagunicodestring) Local $soa = DllStructCreate($tagobjectattributes) Local $sisb = DllStructCreate($tagiostatusblock) DllStructSetData($szname, 1, $regkey) $ret = DllCall($hntdll, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sus), "ptr", DllStructGetPtr($szname)) DllStructSetData($soa, "Length", DllStructGetSize($soa)) DllStructSetData($soa, "RootDirectory", Chr(0)) DllStructSetData($soa, "ObjectName", DllStructGetPtr($sus)) DllStructSetData($soa, "Attributes", $obj_case_insensitive) DllStructSetData($soa, "SecurityDescriptor", Chr(0)) DllStructSetData($soa, "SecurityQualityOfService", Chr(0)) Local $ret = DllCall($hntdll, "int", "NtOpenKey", "hwnd*", "", "dword", BitOR($key_write, $key_read), "ptr", DllStructGetPtr($soa)) If NOT nt_success($ret[0]) Then ConsoleWrite("Location: " & $regkey & @CRLF) ConsoleWrite("Error in NtOpenKey : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) Return SetError(1, 0, $ret[0]) EndIf Return $ret[1] EndFunc Func nt_success($status) If 0 <= $status AND $status <= 2147483647 Then Return True Else Return False EndIf EndFunc Func _lsantstatustowinerror($intstatus) Local $isyserror $isyserror = DllCall("Advapi32.dll", "ulong", "LsaNtStatusToWinError", "dword", $intstatus) Return $isyserror[0] EndFunc Func _configtimestamp() Local $timestamp_array, $input2localfiletime[9] If StringLen($cmdline[2]) <> 28 Then ConsoleWrite("Error: Length of date/time is not correct: " & $cmdline[2] & @CRLF) Exit EndIf $timestamp_array = StringSplit(StringReplace($cmdline[2], '"', ""), ":") If $timestamp_array[0] <> 8 Then ConsoleWrite("Error: Not right date/time parameters supplied: " & $timestamp_array[0] & @CRLF) Exit EndIf For $dateinputs = 1 To $timestamp_array[0] If StringIsDigit($timestamp_array[$dateinputs]) <> 1 Then ConsoleWrite("Error: Not right date/time format supplied: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 2 AND StringLen($timestamp_array[$dateinputs]) <> 4 AND $dateinputs <> 7 Then ConsoleWrite("Error: Not right date/time format supplied: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 3 AND $dateinputs = 7 Then ConsoleWrite("Error: Not right date/time format supplied for MilliSec: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf If StringLen($timestamp_array[$dateinputs]) <> 4 AND $dateinputs = 8 Then ConsoleWrite("Error: Not right date/time format supplied for NanoSec: " & $timestamp_array[$dateinputs] & @CRLF) Exit EndIf Next $input2localfiletime[0] = _wintime_systemtimetolocalfiletime($timestamp_array[1], $timestamp_array[2], $timestamp_array[3], $timestamp_array[4], $timestamp_array[5], $timestamp_array[6], $timestamp_array[7], -1) $input2localfiletime[1] = $timestamp_array[1] $input2localfiletime[2] = $timestamp_array[2] $input2localfiletime[3] = $timestamp_array[3] $input2localfiletime[4] = $timestamp_array[4] $input2localfiletime[5] = $timestamp_array[5] $input2localfiletime[6] = $timestamp_array[6] $input2localfiletime[7] = $timestamp_array[7] $input2localfiletime[8] = $timestamp_array[8] Return $input2localfiletime EndFunc Func _fillzero($inp) Local $inplen, $out, $tmp = "" $inplen = StringLen($inp) For $i = 1 To 4 - $inplen $tmp &= "0" Next $out = $tmp & $inp Return $out EndFunc Func _validate_parameters() If $cmdline[0] <> 3 AND $cmdline[0] <> 1 Then ConsoleWrite("Error: Incorrect number of parameters supplied: " & $cmdline[0] & @CRLF) ConsoleWrite("Examples:" & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Setting the LastWriteTime timestamp on a specific key under the the SOFTWARE key under HKLM:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine\Software\something" "2000:01:01:00:00:00:789:1234" -n' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Retrieving the LastWriteTime timestamp on the SOFTWARE key under HKLM:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine\Software"' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Setting the LastWriteTime timestamp recursively through the whole registry:" & @CRLF) ConsoleWrite('SetRegTime.exe "\Registry\Machine" "2000:01:01:00:00:00:789:1234" -s' & @CRLF) ConsoleWrite("" & @CRLF) ConsoleWrite("Format of timestamp is important and will be interpreted as: YYYY:MM:DD:HH:MM:SS:MSMSMS:NSNSNSNS" & @CRLF) ConsoleWrite("Remember that timestamp supplied will be taken as UTC (not adjusted for timezone configuration)" & @CRLF) Exit EndIf EndFunc Func _ntquerykey($rootdirectory, $objectname, $desiredaccess, $nullchars = 0) Local $specialret[2] Local $disposition, $ret, $keyhandle Local $szname = DllStructCreate("wchar[260]") Local $sus = DllStructCreate($tagunicodestring) Local $soa = DllStructCreate($tagobjectattributes) Local $sisb = DllStructCreate($tagiostatusblock) DllStructSetData($szname, 1, $rootdirectory) $ret = DllCall($hntdll, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sus), "ptr", DllStructGetPtr($szname)) DllStructSetData($soa, "Length", DllStructGetSize($soa)) DllStructSetData($soa, "RootDirectory", 0) DllStructSetData($soa, "ObjectName", DllStructGetPtr($sus)) DllStructSetData($soa, "Attributes", $obj_case_insensitive) DllStructSetData($soa, "SecurityDescriptor", 0) DllStructSetData($soa, "SecurityQualityOfService", 0) $ret = DllCall($hntdll, "int", "NtOpenKey", "hwnd*", "", "dword", $desiredaccess, "ptr", DllStructGetPtr($soa)) If NOT nt_success($ret[0]) Then ConsoleWrite("Location: " & $rootdirectory & @CRLF) ConsoleWrite("Error in NtOpenKey 1 : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) Return SetError(1, 0, $ret[0]) EndIf $handle = $ret[1] DllStructSetData($szname, 1, $objectname) $ret = DllCall($hntdll, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sus), "ptr", DllStructGetPtr($szname)) DllStructSetData($sus, "Length", DllStructGetData($sus, "Length") + $nullchars) DllStructSetData($sus, "MaximumLength", DllStructGetData($sus, "MaximumLength") + $nullchars) DllStructSetData($soa, "Length", DllStructGetSize($soa)) DllStructSetData($soa, "RootDirectory", $handle) DllStructSetData($soa, "ObjectName", DllStructGetPtr($sus)) DllStructSetData($soa, "Attributes", $obj_case_insensitive) DllStructSetData($soa, "SecurityDescriptor", 0) DllStructSetData($soa, "SecurityQualityOfService", 0) $ret = DllCall($hntdll, "int", "NtOpenKey", "hwnd*", "", "dword", $desiredaccess, "ptr", DllStructGetPtr($soa)) If NOT nt_success($ret[0]) Then ConsoleWrite("Location: " & $rootdirectory & "\" & $objectname & @CRLF) ConsoleWrite("Error in NtOpenKey 2 : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) Return SetError(1, 0, $ret[0]) EndIf $handle = $ret[1] Local $skbi = DllStructCreate($tagkeybasicinformation) Local $resultlength Local $ret = DllCall($hntdll, "int", "NtQueryKey", "hwnd", $handle, "dword", $keybasicinformation, "ptr", DllStructGetPtr($skbi), "dword", DllStructGetSize($skbi), "ulong*", $resultlength) If NOT nt_success($ret[0]) Then ConsoleWrite("Error in NtQueryKey : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) Return SetError(1, 0, $ret[0]) EndIf $reglastwritetime = DllStructGetData($skbi, "LastWriteTime") $b = DllStructGetData($skbi, "Title") $c = DllStructGetData($skbi, "NameLength") $d = DllStructGetData($skbi, "Name") $reglastwritetime1 = _wintime_utcfiletimeformat($reglastwritetime - $tdelta, $datetimeformat, 2) $reglastwritetime2 = $reglastwritetime1 & ":" & StringRight($reglastwritetime, 4) $reglastwritetime3 = $reglastwritetime1 & ":" & _fillzero(StringRight($reglastwritetime, 4)) $specialret[0] = $d $specialret[1] = $reglastwritetime3 Return $specialret EndFunc Func _checksubkeys($startkey, $subkey) Local $key, $found = "" Local $disposition, $ret, $keyhandle, $namelengthdiff, $resultlength, $index, $handle, $handle2, $acounter = 1, $atmp Local $szname = DllStructCreate("wchar[260]") Local $sus = DllStructCreate($tagunicodestring) Local $soa = DllStructCreate($tagobjectattributes) Local $sisb = DllStructCreate($tagiostatusblock) DllStructSetData($szname, 1, $startkey) $ret = DllCall($hntdll, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sus), "ptr", DllStructGetPtr($szname)) DllStructSetData($soa, "Length", DllStructGetSize($soa)) DllStructSetData($soa, "RootDirectory", 0) DllStructSetData($soa, "ObjectName", DllStructGetPtr($sus)) DllStructSetData($soa, "Attributes", $obj_case_insensitive) DllStructSetData($soa, "SecurityDescriptor", 0) DllStructSetData($soa, "SecurityQualityOfService", 0) $ret = DllCall($hntdll, "int", "NtOpenKey", "hwnd*", "", "dword", $key_read, "ptr", DllStructGetPtr($soa)) If NOT nt_success($ret[0]) Then ConsoleWrite("Location: " & $startkey & @CRLF) ConsoleWrite("Error in NtOpenKey 1 : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) Return SetError(1, 0, 0) EndIf $handle = $ret[1] DllStructSetData($szname, 1, $subkey) $ret = DllCall($hntdll, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sus), "ptr", DllStructGetPtr($szname)) DllStructSetData($soa, "Length", DllStructGetSize($soa)) DllStructSetData($soa, "RootDirectory", $handle) DllStructSetData($soa, "ObjectName", DllStructGetPtr($sus)) DllStructSetData($soa, "Attributes", $obj_case_insensitive) DllStructSetData($soa, "SecurityDescriptor", 0) DllStructSetData($soa, "SecurityQualityOfService", 0) $ret = DllCall($hntdll, "int", "NtOpenKey", "hwnd*", "", "dword", $key_read, "ptr", DllStructGetPtr($soa)) If NOT nt_success($ret[0]) Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & @CRLF) ConsoleWrite("Error in NtOpenKey 2 : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) Return SetError(1, 0, 0) EndIf $handle = $ret[1] $index = 0 While 1 $ski = DllStructCreate($tagkeynodeinformation) Local $resultlength Local $ret = DllCall($hntdll, "int", "NtEnumerateKey", "hwnd", $handle, "dword", $index, "dword", $keynodeinformation, "ptr", DllStructGetPtr($ski), "dword", DllStructGetSize($ski), "ulong*", $resultlength) If NOT nt_success($ret[0]) AND $ret[0] <> -2147483622 Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & " //$Index=" & $index & @CRLF) ConsoleWrite("Error in NtEnumerateKey : 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) If Hex($ret[0], 8) = "C0000008" Then ExitLoop Return SetError(1, 0, 0) EndIf $ntstatus = "0x" & Hex($ret[0], 8) If $ntstatus = "0x8000001A" Then ExitLoop $namelength = DllStructGetData($ski, "NameLength") $name = DllStructGetData($ski, "Name") $name = StringMid($name, 3, $namelength * 2) Local $formattedname = _hextostring(_removeunicode($name)) $testchars = _fixunicodestring($name) $invalidchars = $testchars[0] $fixedchars = $testchars[1] If $invalidchars = 0 Then Local $soa = DllStructCreate($tagobjectattributes) Local $szname = DllStructCreate("wchar[260]") $namelength = StringLen($name) / 2 Local $sus = DllStructCreate("ushort Length;ushort MaximumLength;ptr Buffer") DllStructSetData($sus, "Length", $namelength) DllStructSetData($sus, "MaximumLength", $namelength + 2) DllStructSetData($sus, "Buffer", DllStructGetPtr($szname)) DllStructSetData($soa, "Length", DllStructGetSize($soa)) DllStructSetData($soa, "RootDirectory", $handle) DllStructSetData($soa, "ObjectName", DllStructGetPtr($sus)) DllStructSetData($soa, "Attributes", $obj_case_insensitive) DllStructSetData($soa, "SecurityDescriptor", 0) DllStructSetData($soa, "SecurityQualityOfService", 0) Local $ret = DllCall($hntdll, "int", "NtOpenKey", "hwnd*", "", "dword", $key_all_access, "ptr", DllStructGetPtr($soa)) If NOT nt_success($ret[0]) Then ConsoleWrite("Location: " & $startkey & "\" & $subkey & "\" & $formattedname & @CRLF) ConsoleWrite("Error in NtOpenKey 3: 0x" & Hex($ret[0], 8) & " -> " & _translateerrorcode(_rtlntstatustodoserror("0x" & Hex($ret[0], 8))) & @CRLF) $index += 1 ContinueLoop EndIf _ntsetinformationkey($ret[1], $keywritetimeinformation, $newtimestamp) EndIf _checksubkeys($startkey & "\" & $subkey, $formattedname) $index += 1 WEnd DllCall($hntdll, "int", "NtClose", "hwnd", $handle) EndFunc Func _fixunicodestring($inp) Local $inplen, $tmp, $appended, $counter = 0, $info[2] If StringLeft($inp, 2) = "0x" Then $inp = StringMid($inp, 3) $inplen = StringLen($inp) For $i = 1 To $inplen Step 4 $tmp = StringMid($inp, $i, 2) If Dec($tmp) < 32 Then $tmp = "2A" $counter += 1 EndIf $appended &= $tmp Next $info[0] = $counter $info[1] = $appended Return $info EndFunc Func _rtlntstatustodoserror($status) Local $acall = DllCall("ntdll.dll", "ulong", "RtlNtStatusToDosError", "dword", $status) If NOT nt_success($acall[0]) Then ConsoleWrite("Error in RtlNtStatusToDosError: " & Hex($acall[0], 8) & @CRLF) Return SetError(1, 0, $acall[0]) Else Return $acall[0] EndIf EndFunc Func _translateerrorcode($errcode) Local $tbufferptr = DllStructCreate("ptr") Local $ncount = _formatmessage(BitOR($__winapiconstant_format_message_allocate_buffer, $__winapiconstant_format_message_from_system), 0, $errcode, 0, $tbufferptr, 0, 0) If @error Then Return SetError(@error, 0, "") Local $stext = "" Local $pbuffer = DllStructGetData($tbufferptr, 1) If $pbuffer Then If $ncount > 0 Then Local $tbuffer = DllStructCreate("wchar[" & ($ncount + 1) & "]", $pbuffer) $stext = DllStructGetData($tbuffer, 1) EndIf _localfree($pbuffer) EndIf Return $stext EndFunc Func _formatmessage($iflags, $psource, $imessageid, $ilanguageid, ByRef $pbuffer, $isize, $varguments) Local $sbuffertype = "struct*" If IsString($pbuffer) Then $sbuffertype = "wstr" Local $aresult = DllCall("Kernel32.dll", "dword", "FormatMessageW", "dword", $iflags, "ptr", $psource, "dword", $imessageid, "dword", $ilanguageid, $sbuffertype, $pbuffer, "dword", $isize, "ptr", $varguments) If @error Then Return SetError(@error, @extended, 0) If $sbuffertype = "wstr" Then $pbuffer = $aresult[5] Return $aresult[0] EndFunc Func _localfree($hmem) Local $aresult = DllCall("kernel32.dll", "handle", "LocalFree", "handle", $hmem) If @error Then Return SetError(@error, @extended, False) Return $aresult[0] EndFunc Func _strtounicode($inp) Local $inplen, $tmp, $appended $inplen = StringLen($inp) For $i = 1 To $inplen $tmp = _stringtohex(StringMid($inp, $i, 1)) $appended &= $tmp & "00" Next Return $appended EndFunc Func _hextounicode($inp) Local $inplen, $tmp, $appended $inplen = StringLen($inp) For $i = 1 To $inplen Step 2 $tmp = StringMid($inp, $i, 2) $appended &= $tmp & "00" Next Return $appended EndFunc Func _removeunicode($inp) Local $inplen, $tmp, $appended If StringLeft($inp, 2) = "0x" Then $inp = StringMid($inp, 3) $inplen = StringLen($inp) For $i = 1 To $inplen Step 4 $tmp = StringMid($inp, $i, 2) $appended &= $tmp Next Return $appended EndFunc Func _end($begin) Local $timerdiff = TimerDiff($begin) $timerdiff = Round(($timerdiff / 1000), 2) ConsoleWrite("Job took " & $timerdiff & " seconds" & @CRLF) EndFunc You can see that function _WinTime_UTCFileTimeToLocalFileTime that throws error in line 618 of original code is completely unchanged. Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 The bad thing the extracted code won't compile to a working EXE but it will run (Tools > Go) from SciTE-Editor. However it won't work throwith this error: "C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime.au3" "\Registry\Machine\Software\Adobe " "2000:01:01:00:00:00:789:1234" -n>"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime.au3" "\Registry\Machine\Software\Adobe Starting SetRegTime by Joakim Schicht Version 1.0.0.5 Your current local time (timezone and/or daylight saving) is 5 hours off UTC Location: "\Registry\Machine\Software Error in NtOpenKey 1 : 0xC000003B -> Óêàçàí íåäîïóñòèìûé ïóòü. Ntstatus: 0xC000003B 0xC000003B stays for STATUS_OBJECT_PATH_SYNTAX_BAD and according to this post it should be a different path for registry key or something like that. I tried double backslash - same error. What is the correct way to do overcome such error? Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 As it's not possible to edit posts, I'd like to add to my previous post that it partially works (reading timestamp works) but I'm having trouble with ":" symbol in my parameters, it definitely breaks the input and results in 0xC000003B: "C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" "\Registry\Machine\Software\Adobe" >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" "\Registry\Machine\Software\Adobe" Starting SetRegTime by Joakim Schicht Version 1.0.0.5 Your current local time (timezone and/or daylight saving) is 5 hours off UTC The key: Adobe has LastWriteTime timestamp: 2000-01-01 00:00:00:789:1234 >Exit code: 0 "C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" "\Registry\Machine\Software\Adobe" "2000:01:01:00:00:00:789:1234" -n>"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" "\Registry\Machine\Software\Adobe Starting SetRegTime by Joakim Schicht Version 1.0.0.5 Your current local time (timezone and/or daylight saving) is 5 hours off UTC Location: "\Registry\Machine\Software Error in NtOpenKey 1 : 0xC000003B -> Óêàçàí íåäîïóñòèìûé ïóòü. Ntstatus: 0xC000003B Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 How to input ":" as command parameter to SciTE-Editor correctly? Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 Sorry for extra posts I'm using old ASUS X58L laptop from 2008 which has 2 GB RAM, forum editor engine is too heavy for my machine. If someone could advise where I can turn off all forum's bangs and whistles and get to something less resource-heavy I'll be grateful! Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 33 minutes ago, tinygoblin said: How to input ":" as command parameter to SciTE-Editor correctly? Using single quotes to save double quotes like this doesn't help: "C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" '"'\Registry\Machine\Software\Adobe'"''"'2000:01:01:00:00:00:789:1234' "' -n" "C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" "'\Registry\Machine\Software\Adobe' '2000:01:01:00:00:00:789:1234' -n" Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
argumentum Posted November 29, 2022 Share Posted November 29, 2022 8 minutes ago, tinygoblin said: Using single quotes Run("cmd /c ""dir&&pause"" ") tinygoblin 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 46 minutes ago, argumentum said: Run("cmd /c ""dir&&pause"" ") I'm familiar with that from BAT scripting but cannot figure out how to pass it to SciTE-Lite's console command like: "C:\SetRegTime_.exe" "\Registry\Machine\Software\Adobe" "2000:01:01:00:00:00:789:1234" -n "C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" "\Registry\Machine\Software\Adobe" "2000:01:01:00:00:00:789:1234" -n This is how I do it in BAT to write Last Access Time for pre-compiled SetRegTime.exe 1.0.0.5: echo off set arg1=\Registry\Machine\System\ControlSet001\Control set arg2=2000:01:01:00:00:00:789:1234 start cmd /c " "C:\SetRegTime.exe" %arg1% %arg2% -n && pause" and to read LAT: echo off set arg1=\Registry\Machine\System\ControlSet001\Control start cmd /c " "C:\SetRegTime.exe" %arg1% && pause" This works for pre-compiled exe. But I have trouble sending parameters via SciTE to try troubleshoot. Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 I figured: it works if no quotes are being used if there're no spaces in path, i.e. "C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" /ErrorStdOut "C:\SetRegTime_.au3" \Registry\Machine\System\ControlSet001\Control 2020:01:01:00:00:00:789:1234 -n So I can execute extracted SetRegTime code from this post from SciTE-Lite now with 3 parameters: none, -n and -s. But -n and -s provide similar result: just first registry key is being processed. No errors and no "Location" in the output. P.S. Adobe has nothing to do with this thread, it was just the top most key in Software branch of Windows registry. This research is not related to piracy in any way. argumentum 1 Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
tinygoblin Posted November 29, 2022 Author Share Posted November 29, 2022 In the previous post I meant that I get no errors and no "Location: " in the output if the -s switch is used. I have tried swapping NtOpenKey to RegOpenKey with this half-working code to check if it will work at least for -n mode but sadly it doesn't work (looks like NtOpenKey is like a parent of RegOpenKey and thus can do more things or something). Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
argumentum Posted November 29, 2022 Share Posted November 29, 2022 (edited) 7 hours ago, tinygoblin said: 1) one is related on legacy AutoIt functions by Ascend4nt _WinTimeFunctions.au3 (won't allow compiling because of wrong declaration in line 618) ISN AutoIt Studio uses that UDF so stands to reason that is kept updated. Fetch that source code. It may fix the problems you are encountering. edit: I see that you found a way around it. Sorry for posting non-sense 😅 Edited November 29, 2022 by argumentum oops Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
tinygoblin Posted December 2, 2022 Author Share Posted December 2, 2022 On 11/29/2022 at 11:32 PM, argumentum said: ISN AutoIt Studio uses that UDF so stands to reason that is kept updated. Fetch that source code. It may fix the problems you are encountering. edit: I see that you found a way around it. Sorry for posting non-sense 😅 Not nonsense at all, thank you, I tried extracting probably updated functions but it didn't help. Only direct extraction of EXE code works, I mean partially works (no -s recursive mode) 😞. argumentum 1 Слава Україні! Героям слава! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now