Что нового

Ошибка при использовании DllCall

Cornet

Знающий
Сообщения
38
Репутация
6
Написал вот такой код (не то чтобы весь - большую часть позаимствовал тут https://www.autoitscript.com/forum/topic/82701-_ads-udf/page/2/?tab=comments#comment-593163) для переноса атрибутов и всех 4 дат создания/модификации файла:
Код:
Opt("MustDeclareVars", 1)

Global Const $FileBasicInformation = 4

Global Const $GENERIC_READ = 0x80000000
Global Const $GENERIC_WRITE = 0x40000000
Global Const $OBJ_CASE_INSENSITIVE = 0x00000040
Global Const $FILE_DIRECTORY_FILE = 0x00000002
Global Const $FILE_NON_DIRECTORY_FILE = 0x00000040
Global Const $FILE_RANDOM_ACCESS = 0x00000800
Global Const $FILE_SHARE_READ = 0x1
Global Const $FILE_SHARE_WRITE = 0x00000002

Global Const $tagFileBasicInformation = "int64 CreationTime;int64 LastAccessTime;int64 LastWriteTime;int64 ChangeTime;ulong FileAttributes"
Global Const $tagIOSTATUSBLOCK = "dword Status;dword 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"

CopyDateAndAttrib("D:\5\развертка уп марм микс-c.eps", "D:\5\развертка уп марм микс-c-new.eps")
ConsoleWrite("end prog" & @CRLF)

Func CopyDateAndAttrib($file1, $file2, $mode = 0) ; 0 = file, 1 = directory
	Local $hNTDLL = DllOpen("ntdll.dll")
	Local $szName = DllStructCreate("wchar[260]")
	Local $sUS = DllStructCreate($tagUNICODESTRING)
	Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES)
	Local $sISB = DllStructCreate($tagIOSTATUSBLOCK)
	Local $buffer = DllStructCreate("byte[16384]")
	Local $ret, $FILE_MODE

	If $mode == 0 Then
		$FILE_MODE = $FILE_NON_DIRECTORY_FILE
	Else
		$FILE_MODE = $FILE_DIRECTORY_FILE
	EndIf



	Local $file = "\??\" & $file1
	ConsoleWrite($file & @CRLF)

	DllStructSetData($szName, 1, $file)
	$ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName))
	ConsoleWrite("Length: " & DllStructGetData($sUS, "Length") & @CRLF)
	ConsoleWrite("Max: " & DllStructGetData($sUS, "MaximumLength") & @CRLF)
	ConsoleWrite("Buff ptr: " & DllStructGetData($sUS, "Buffer") & @CRLF)

	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))
	ConsoleWrite("-----" & @CRLF)

	$ret = DllCall($hNTDLL, "int", "NtOpenFile", "hwnd*", "", "dword", $GENERIC_READ, "ptr", DllStructGetPtr($sOA), "ptr", DllStructGetPtr($sISB), "ulong", $FILE_SHARE_READ, "ulong", BitOR($FILE_MODE, $FILE_RANDOM_ACCESS))
	ConsoleWrite("Return Open File 1: " & Hex($ret[0]) & @CRLF)
	Local $hFile1 = $ret[1]



	ConsoleWrite("+++" & @CRLF)
	ConsoleWrite("hFile: " & $hFile1 & @CRLF)

	$ret = DllCall($hNTDLL, "int", "NtQueryInformationFile", "hwnd", $hFile1, "ptr", DllStructGetPtr($sISB), "ptr", DllStructGetPtr($buffer), "int", 16384, "int", $FileBasicInformation)

	ConsoleWrite("Return: " & Hex($ret[0]) & @CRLF)


	If NT_SUCCESS($ret[0]) Then
		ConsoleWrite("->Successful query." & @CRLF)
		ConsoleWrite(">$buffer: " & $buffer & @CRLF)
		Local $pFBI = DllStructGetPtr($buffer)
		Local $sFBI = DllStructCreate($tagFileBasicInformation, $pFBI)
		Local $CreationTime = DllStructGetData($sFBI, "CreationTime")
		Local $LastAccessTime = DllStructGetData($sFBI, "LastAccessTime")
		Local $LastWriteTime = DllStructGetData($sFBI, "LastWriteTime")
		Local $ChangeTime = DllStructGetData($sFBI, "ChangeTime")
		Local $FileAttributes = DllStructGetData($sFBI, "ChangeTime")
		ConsoleWrite(">$CreationTime: " & $CreationTime & @CRLF)
		ConsoleWrite(">$LastAccessTime: " & $LastAccessTime & @CRLF)
		ConsoleWrite(">$LastWriteTime: " & $LastWriteTime & @CRLF)
		ConsoleWrite(">$ChangeTime: " & $ChangeTime & @CRLF)
	Else
		ConsoleWrite("!->Not Successful query." & @CRLF)
	EndIf

	Local $file = "\??\" & $file2
	ConsoleWrite($file & @CRLF)

	DllStructSetData($szName, 1, $file)
	$ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName))
	ConsoleWrite("Length: " & DllStructGetData($sUS, "Length") & @CRLF)
	ConsoleWrite("Max: " & DllStructGetData($sUS, "MaximumLength") & @CRLF)
	ConsoleWrite("Buff ptr: " & DllStructGetData($sUS, "Buffer") & @CRLF)

	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))
	ConsoleWrite("-----" & @CRLF)

	$ret = DllCall($hNTDLL, "int", "NtClose", "hwnd", $hFile1)
	ConsoleWrite("Return Close $hFile1: " & Hex($ret[0]) & @CRLF)

	$ret = DllCall($hNTDLL, "int", "NtOpenFile", "hwnd*", "", "dword", $GENERIC_WRITE, "ptr", DllStructGetPtr($sOA), "ptr", DllStructGetPtr($sISB), "ulong", $FILE_SHARE_WRITE, "ulong", BitOR($FILE_MODE, $FILE_RANDOM_ACCESS))
	ConsoleWrite("Return Open File 2: " & Hex($ret[0]) & @CRLF)
	Local $hFile2 = $ret[1]

	ConsoleWrite("hFile2: " & $hFile2 & @CRLF)
	$ret = DllCall($hNTDLL, "int", "NtSetInformationFile", "hwnd", $hFile2, "ptr", DllStructGetPtr($sISB), "ptr", DllStructGetPtr($sFBI), "int", DllStructGetSize($sFBI), "int", $FileBasicInformation)
	ConsoleWrite("Return Set Information File: " & Hex($ret[0]) & @CRLF)

	$ret = DllCall($hNTDLL, "int", "NtClose", "hwnd", $hFile2)
	ConsoleWrite("Return Close $hFile2: " & Hex($ret[0]) & @CRLF)

	DllClose($hNTDLL)
	ConsoleWrite("end func" & @CRLF)

EndFunc   ;==>CopyDateAndAttrib


Func NT_SUCCESS($status)
	ConsoleWrite("NT_SUCCESS" & @CRLF)
	If 0 <= $status And $status <= 0x7FFFFFFF Then
		Return True
	Else
		Return False
	EndIf
EndFunc   ;==>NT_SUCCESS


И собсвенно все работает, но...
1. всегда вылетает с ошибкой (AutoIt3.exe ended.rc:-1073740940) при выходе из функции CopyDateAndAttrib
2. переодически вылетает в любой части скрипта с такой же ошибкой.

Посоветуйте что-нибудь (FileGetTime не подходит - не все данные), может кто ни будь уже написал, а я не смог найти ;)

Win10. Версия Auto-it 3.3.14.1
 

joiner

Модератор
Локальный модератор
Сообщения
3 055
Репутация
511
проверил несколько раз - ошибки нет. то есть , нет завершения работы с таким кодом. все нормально
Вин 10 х64
AutoIt 3.3.12.0
 
Автор
C

Cornet

Знающий
Сообщения
38
Репутация
6
Спасибо за проверку, в откомпилированном виде у меня тоже все заработало без ошибок.
Чертова криво повешенная админами винда. Причем с COM объектами диаметрально противоположная проблема - в SciTE все запускается, а компилированное нет (
 
Верх