How do I call an Exception with a resource string message using inline assembler?
I tried various things, but nothing seems to work. I get things like inline assembler syntax error or operant sizes does not match.
resourcestring
sMessage = 'Test 123';
procedure foo;
asm
mov eax, #sMessage
push eax
call Exception.CreateRes
end;
An iOS quick action / shortcut item is received by the app delegate's implementation of application(_:performActionFor:completionHandler:).
In that implementation, you are supposed to call the completionHandler. It takes a Bool.
Does anyone know what the Bool is for? I see no difference regardless of whether I pass true or false. (In fact, I see no difference even if I neglect to call the completionHandler!)
Short answer: parameter is not used in implementation of block in iOS 10 (guess that in iOS 9 too, but can't check right now).
Long answer: let's see what happens inside of completion block:
___50-[UIApplication _handleApplicationShortcutAction:]_block_invoke:
push rbp ; XREF=-[UIApplication _handleApplicationShortcutAction:]+132
mov rbp, rsp
mov rax, qword [ds:rdi+0x20]
mov rdx, qword [ds:rdi+0x28]
mov rsi, qword [ds:0x1179e88] ; #selector(_updateSnapshotAndStateRestorationWithAction:)
mov rdi, rax ; argument "instance" for method imp___got__objc_msgSend
pop rbp
jmp qword [ds:imp___got__objc_msgSend]
; endp
I run this on Intel64, so first argument should be stored in rdi register (when we calling block under ARC it is an instance of NSMallocBlock). There is no selector, so second parameter (bool argument) should be stored in rsi register. But rsi register is not used in code - it just sends message _updateSnapshotAndStateRestorationWithAction: to object ds:rdi+0x20 with argument ds:rdi+0x28.
Both ds:rdi+0x20 and ds:rdi+0x28 are captured pointers inside of the block.
Think that the guess with parameter as indicator for snapshot function was wrong.
I am working with masm 32. I want to process bitmap images. But I don't know how to get an image or save an image.
I have no idea about processing images with masm.
Any information will help me.
Thanks
This might get you started... This is basic code to load in a bitmap and display it on a dialog box. I'm not sure what mean by 'processing' bitmap images, I suspect you need something more complex. However, this might get you started...
.386
.model flat,stdcall
option casemap:none
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib gdi32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
IDD_DIALOG equ 1000
IDC_BITMAP equ 100
IDM_MENU equ 10000
.const
ClassName db 'DLGCLASS',0
.data?
hInstance dd ?
CommandLine dd ?
hWnd dd ?
hBitmap dd ?
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke GetCommandLine
invoke InitCommonControls
mov CommandLine,eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov wc.cbSize,sizeof WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc,offset WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName,offset ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,addr wc
invoke CreateDialogParam,hInstance,IDD_DIALOG,NULL,addr WndProc,NULL
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
.while TRUE
invoke GetMessage,addr msg,NULL,0,0
.BREAK .if !eax
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL ps:PAINTSTRUCT
LOCAL hdc:HDC
LOCAL hMemDC:HDC
LOCAL rect:RECT
mov eax,uMsg
.if eax==WM_INITDIALOG
push hWin
pop hWnd
; Load up the bitmap
invoke LoadBitmap, hInstance, IDC_BITMAP
mov hBitmap, eax
.elseif eax==WM_COMMAND
mov eax,wParam
mov edx, eax
shr edx, 16
.if lParam==0
.if eax==IDM_FILE_EXIT
invoke SendMessage,hWin,WM_CLOSE,0,0
.elseif eax==IDM_HELP_ABOUT
invoke ShellAbout,hWin,addr AppName,addr AboutMsg,NULL
.endif
.else
.endif
.elseif eax==WM_PAINT
invoke BeginPaint, hWnd, addr ps
mov hdc, eax
invoke CreateCompatibleDC, hdc
mov hMemDC, eax
invoke SelectObject, hMemDC, hBitmap
invoke GetClientRect, hWnd, addr rect
invoke BitBlt, hdc, 10, 10, rect.right, rect.bottom, hMemDC, 0, 0, SRCAND
invoke DeleteDC, hMemDC
invoke EndPaint, hWnd, addr ps
.elseif eax==WM_CLOSE
invoke DestroyWindow,hWin
.elseif uMsg==WM_DESTROY
invoke DeleteObject, hBitmap
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
end start
Note the LoadBitmap API call and the WM_PAINT routine.
..Forgot the .rc file...
#define IDD_DIALOG 1000
#define IDC_BITMAP 100
IDC_BITMAP BITMAP DISCARDABLE "myfile.bmp"
I have downloaded and started playing with Pascalscript and its sample programs.
I have come across a problem with interfacing to Forms using the Forms access sample script.
It works in 32 bit mode, in 64 bit mode no events get triggered.
That is, a buttons onpress event never calls the pascalscript onpress code.
I am using Delphi 10 Seattle on windows 7 pro.
Any ideas on how to get scripts working right on the 64 bit platform?
Well seeing as no one had an answer to this I had to do the hard work myself.
So the problem was empty prolog code for x64 in the conversion from delphi to pascalscript method calling which was written in assembler. The empty method handler was called "MyAllMethodhandler" in the uPSruntime unit and my code solution is as follows
function MyAllMethodsHandler2(Self:PScriptMethodInfo; const Stack:PPointer; _EDX,_ECX:Pointer):Integer; forward;
{$ifdef CPUX64}
procedure MyAllMethodsHandler;
// On entry:
// RCX = Self pointer
// RDX, R8, R9 = param1 .. param3
// STACK = param4... paramcount
asm
PUSH R9
MOV R9,R8 // R9:=_ECX
MOV R8,RDX // R8:=_EDX
MOV RDX, RSP // RDX:=Stack
SUB RSP, 20h
CALL MyAllMethodsHandler2
ADD RSP, 20h //Restore stack
POP R9
end;
{$else}
procedure MyAllMethodsHandler; //original x86 code
// On entry:
// EAX = Self pointer
// EDX, ECX = param1 and param2
// STACK = param3... paramcount
asm
push 0
push ecx
push edx
mov edx, esp
add edx, 16 // was 12
pop ecx
call MyAllMethodsHandler2
pop ecx
mov edx, [esp]
add esp, eax
mov [esp], edx
mov eax, ecx
end;
{$endif}
Not sure if this will work with everything but seems to work for at least 2 parameters.
I'll post it as a comment on GitHub, I can't really fix it directly as I have made extensive changes to the whole of Pascal script so it supports complex math.
I'm developing a program in Delphi 2010 that has to save the logs that are stored in a Tmemo. I'm trying to create a log file for everyday in which I append the logs from a memo.After I append the text I clear the content of the memo. So in the location of my app i want to create a folder named "loguri-mover_ftp" in which i want to store the log file. EX: log_mover-ftp_2-16-2015.txt
The code I use for this is:
If DirectoryExists(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp') then
begin
TFile.AppendAllText(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp\log_mover-ftp_' + datetostr(now) + '.txt',memo_loguri.lines.text, TEncoding.UTF8);
Memo_loguri.lines.text:='';
end
else
begin
CreateDir(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp');
TFile.AppendAllText(ExtractFilePath(Application.ExeName) + 'loguri-mover_ftp\log_mover-ftp_' + datetostr(now) + '.txt',memo_loguri.lines.text, TEncoding.UTF8);
Memo_loguri.lines.text:='';
end;
Because I'm interested in the stability of my application I've enabled the MadExcept debugger inside my app. After 2 hours 12 minutes i get the following error:
exception class : EDirectoryNotFoundException
exception message : The specified path was not found.
compiled with : Delphi 2010
program up time : 2 hours 12 minutes
madExcept version : 4.0.7
callstack crc : $bed2c7c0, $c58f696b, $05cb237f
count : 5
exception number : 1
disassembling:
[...]
005ce40a push eax
005ce40b call -$13ee30 ($48f5e0) ; SysUtils.TEncoding.GetUTF8
005ce410 mov ecx, eax
005ce412 pop eax
005ce413 pop edx
005ce414 > call -$1144ad ($4b9f6c) ; IOUtils.TFile.AppendAllText
005ce419 775 mov eax, [ebp+8]
005ce41c mov eax, [eax+$2a0]
005ce422 xor edx, edx
005ce424 mov ecx, [eax]
005ce426 call dword ptr [ecx+$2c]
[...]
What am I doing wrong?
The exception is raised by the call to AppendAllText. If you follow the source for that function you will find a call to InternalCheckFilePathParam, the implementation of which looks like this:
class procedure TFile.InternalCheckFilePathParam(const Path: string;
const FileExistsCheck: Boolean);
begin
if (Length(Path) >= MAX_PATH - TFile.FCMinFileNameLen) and
(not TPath.IsExtendedPrefixed(Path)) then
raise EPathTooLongException.CreateRes(#SPathTooLong);
if not TPath.HasPathValidColon(Path) then
raise ENotSupportedException.CreateRes(#SPathFormatNotSupported);
if Trim(Path) = '' then // DO NOT LOCALIZE
raise EArgumentException.CreateRes(#SInvalidCharsInPath);
if not TPath.HasValidPathChars(Path, False) then
raise EArgumentException.CreateRes(#SInvalidCharsInPath);
if not TDirectory.Exists(TPath.DoGetDirectoryName(TPath.DoGetFullPath(Path))) then
raise EDirectoryNotFoundException.CreateRes(#SPathNotFound);
if FileExistsCheck and (not Exists(Path)) then
raise EFileNotFoundException.CreateRes(#SFileNotFound);
end;
Now, Path is the first argument that you passed to AppendAllText. Since EDirectoryNotFoundException is being raised, we can conclude that the directory containing Path does not exist.
Of course, this seems odd give that you check for its existence and then create it. I think the mystery can be solved by looking at what datetostr(now) returns. You imagine that the date separator used is -. But what if the date separator is /? In that case the / will be interpreted as a path delimiter.
The solution is to specify the date separator explicitly by using the DateToStr overload that accepts a TFormatSettings parameter.
I also cannot ignore the duplication in your code. Please don't ever repeat magic strings the way you do. The code should look like this:
LogFileDir := TPath.Combine(ExtractFilePath(Application.ExeName), 'loguri-mover_ftp');
if not DirectoryExists(LogFileDir) then
ForceDirectories(LogFileDir);
DateStr := DateToStr(Now, ...); // you supply an appropriate TFormatSettings
LogFilePath := TPath.Combine(LogFileDir, log_mover-ftp_' + DateStr + '.txt');
TFile.AppendAllText(LogFilePath, memo_loguri.lines.text, TEncoding.UTF8);