News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

UASM 2.46 Release

Started by johnsa, December 05, 2017, 01:11:19 AM

Previous topic - Next topic

johnsa

Hi,

I've just written the same code in C for comparison and run both. Your code works for me here and sets the desktop wallpaper.

The C-code looks as follows for a COM invocation:


pAD->SetWallpaper((PCWSTR)&DesktopImg, 0);
013D17E4 6A 00                push        0 
013D17E6 8D 45 C0             lea         eax,[DesktopImg] 
013D17E9 50                   push        eax 
013D17EA 8B 4D F4             mov         ecx,dword ptr [pAD] 
013D17ED 8B 11                mov         edx,dword ptr [ecx] 
013D17EF 8B 45 F4             mov         eax,dword ptr [pAD] 
013D17F2 50                   push        eax 
013D17F3 8B 4A 14             mov         ecx,dword ptr [edx+14h] 
013D17F6 FF D1                call        ecx 


and from uasm:


  _VCOMINVOKE    pAD,IActiveDesktop,SetWallpaper,ADDR DesktopImg,0
  ; pAD->SetWallpaper(OFFSET DesktopImg,0) identical code generated
01081031  mov         eax,dword ptr ds:[01083032h] 
01081036  mov         eax,dword ptr [eax] 
01081038  push        0 
0108103A  push        1083020h 
0108103F  push        dword ptr ds:[1083032h] 
01081045  call        dword ptr [eax+14h] 


As you can see in the C version, we have PUSH 0, PUSH ADDRESS OF ImageName, and most importantly.. the THIS ptr...
013D17EF 8B 45 F4             mov         eax,dword ptr [pAD] 
013D17F2 50                   push        eax

So we're doing it the same and both have identical results for me in C and ASM.

C code for reference:

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int main()
{
IActiveDesktop *pAD = NULL;
WALLPAPEROPT wpo;

wchar_t DesktopImg[] = L"apicture.jpg";

CoInitializeEx(0,COINIT_APARTMENTTHREADED);
CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&pAD);

memset(&wpo, 0, sizeof(WALLPAPEROPT));
wpo.dwSize = sizeof(WALLPAPEROPT);
wpo.dwStyle = WPSTYLE_CENTER;

pAD->SetWallpaper((PCWSTR)&DesktopImg, 0);

pAD->Release();

CoUninitialize();

    return 0;
}


jj2007

Quote from: johnsa on December 13, 2017, 07:53:50 AM
C code for reference:

I love it :icon_mrgreen:Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

Tmp.cpp
c:\program files (x86)\microsoft visual studio 10.0\vc\include\codeanalysis\sourceannotations.h(78): warning C4467: usage of ATL attributes is deprecated
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\ShlObj.h(1151): warning C4091: 'typedef ': ignored on left of 'tagGPFIDL_FLAGS' when no variable is declared
Tmp.cpp(10): error C2065: 'IActiveDesktop': undeclared identifier
Tmp.cpp(10): error C2065: 'pAD': undeclared identifier
Tmp.cpp(11): error C2065: 'WALLPAPEROPT': undeclared identifier
Tmp.cpp(11): error C2146: syntax error: missing ';' before identifier 'wpo'
Tmp.cpp(11): error C2065: 'wpo': undeclared identifier
Tmp.cpp(13): warning C4129: 'M': unrecognized character escape sequence
Tmp.cpp(13): warning C4129: 'A': unrecognized character escape sequence
Tmp.cpp(13): warning C4129: 'C': unrecognized character escape sequence
Tmp.cpp(16): error C2065: 'pAD': undeclared identifier
Tmp.cpp(18): error C2065: 'wpo': undeclared identifier
Tmp.cpp(18): error C2065: 'WALLPAPEROPT': undeclared identifier
Tmp.cpp(19): error C2065: 'wpo': undeclared identifier
Tmp.cpp(19): error C2228: left of '.dwSize' must have class/struct/union
Tmp.cpp(19): note: type is 'unknown-type'
Tmp.cpp(19): error C2065: 'WALLPAPEROPT': undeclared identifier
Tmp.cpp(20): error C2065: 'wpo': undeclared identifier
Tmp.cpp(20): error C2228: left of '.dwStyle' must have class/struct/union
Tmp.cpp(20): note: type is 'unknown-type'
Tmp.cpp(20): error C2065: 'WPSTYLE_CENTER': undeclared identifier
Tmp.cpp(22): error C2065: 'pAD': undeclared identifier
Tmp.cpp(22): error C2227: left of '->SetWallpaper' must point to class/struct/union/generic type
Tmp.cpp(22): note: type is 'unknown-type'
Tmp.cpp(24): error C2065: 'pAD': undeclared identifier
Tmp.cpp(24): error C2227: left of '->Release' must point to class/struct/union/generic type
Tmp.cpp(24): note: type is 'unknown-type'


What's in your stdafx.h? Is the wpo needed at all?
MSDN says it's supported under XP and earlier - does it work on Win7 and higher...? I can build it in assembler, I get S_OK all the time but no wallpaper is set :(

johnsa

I'm on Windows 10 and it seems to work for me, there is more code however to complete the operation properly, i believe you need to apply the change..

something along these lines (and this also lists the required headers) :



#include "windows.h"
#include "wininet.h"
#include "shlobj.h"
#include "wchar.h"
#include <iostream>

void  SetWallpaper(LPCWSTR file){
    CoInitializeEx(0,COINIT_APARTMENTTHREADED);
    IActiveDesktop* desktop;
    HRESULT status =       CoCreateInstance(CLSID_ActiveDesktop,NULL,CLSCTX_INPROC_SERVER,IID_IActiveDesktop,(void**)&desktop);
    WALLPAPEROPT wOption;
    ZeroMemory(&wOption, sizeof(WALLPAPEROPT));
    wOption.dwSize=sizeof(WALLPAPEROPT);
    wOption.dwStyle = WPSTYLE_CENTER;
    status = desktop->SetWallpaper(file,0);
    wcout << status << endl;
    status = desktop->SetWallpaperOptions(&wOption,0);
    wcout << status << endl;
    status = desktop->ApplyChanges(AD_APPLY_ALL);
    wcout << status << endl;
    desktop->Release();
    CoUninitialize();
}
int wmain(int argc, wchar* argv[]){
    if(argc<=1){
        wcout << "use: " << argv[0] <<" path_to_pic.bmp" <<endl;
    }else{
        wchar_t* file = argv[1];
        SetWallpaper(file);
    }
    getchar();
    return 0;
}



jj2007

Thanks, John, I'll check it tomorrow :icon14:

My current code is here.

johnsa

Updated packages will be publish shortly for 2.46.5.

I've started including the sub version number on the site so it's easier to see which is current , apart from checking the date.

Changes are:
1) Included a new oo3.sample that shows how to invoke methods from inside methods using thisPtr and pointer syntax.

mov rsi,thisPtr
assume rsi:PTR Person

mov rax,lstrlen([rcx].pName)
WriteConsole( [rsi].handle, [rsi].pName, eax, ADDR bWritten, NULL )

assume rsi:NOTHING

; calls to other instance methods with pointer syntax.
; -> Because the METHOD declaration sets the prototype, you cannot forward reference methods.
thisPtr->SetName("New name")

mov rcx,thisPtr
mov rax,[rcx].handle
mov rbx,[rcx].pName
invoke WriteConsole, rax, rbx, 8, ADDR bWritten, NULL

; calls to other instance methods with pointer syntax using a register.
lea rcx,thisPtr
[rcx].Person->SetName("New name")


2) Added a bunch of new regression tests and fixed some evex support queries around usage in macros, including decorators { } being passed in and out of macros and equate substitution in evex expressions.


vsubpd zmm0 {KMASK}, zmm1, zmm2 ; direct macro substitution works.

;--------------------------------------------------------

znoconst_rounding_single_nottp MACRO zmmval, zmmcarry, kwritemask
    zfmsubpd zmmcarry, {kwritemask}, zmmval, zmm24, zmm20
    zfmsubpd zmm16, {kwritemask}, zmmcarry, zmm26, zmm22
    vsubpd zmmval {kwritemask}, zmmval, zmm16
ENDM

;--------------------------------------------------------

znoconst MACRO zmmval, kwritemask
   vsubpd zmmval {kwritemask}, zmmval, zmm16
   ; multiple elements can be substituted in the macro, include
   ; placeholder for register and decorator.
   vsubpd zmm2 {kwritemask}, zmmval, zmm16
   ; register + expanded decorator from macro parameter works.



3) Added optimisation, previously a 0 valued immediate would be optimised to an xor during invoke, now the same applies to zero-valued equates.


johnsa

Another note to include is that I've also added support for the C style calls to handle equates.

We parse the high level calls before any form of expansion or substitution on the line, but can now handle something like:

WriteConsoleA EQU <__imp_WriteConsoleA>
WriteConsole EQU <WriteConsoleA>

WriteConsole( ... )

By traversing the equates to see if they evaluate to a real procedure either locally defined in the project or marked as external.

Vortex

Hi johnsa,

Thanks for your help :t I got it to work. The pointer to the interface ( pAD ) should be passed to the stack, that's right, I was mistaken.

Both of the syntaxes are working fine :

    pAD->SetWallpaper(OFFSET DesktopImg,0)
    pAD->SetWallpaperOptions(OFFSET wpo,0)
    pAD->ApplyChanges(AD_APPLY_ALL)
    pAD->Release()

    _VCOMINVOKE pAD,IActiveDesktop,SetWallpaper,ADDR DesktopImg,0
    _VCOMINVOKE pAD,IActiveDesktop,SetWallpaperOptions,OFFSET wpo,0
    _VCOMINVOKE pAD,IActiveDesktop,ApplyChanges,AD_APPLY_ALL
    _VCOMINVOKE pAD,IActiveDesktop,Release

johnsa

Packages and repos updated.

2.46.5 / 14th Dec 2017.

Cheers :)
John

jj2007


LiaoMi

It's just a dream for an assembler language programmer  :t Thanks!

Vortex

#55
Hi johnsa,

Thanks for the new release. Testing the handling of the equates, I get the following error messages :

.386
.model flat,stdcall
option casemap:none

MessageBoxA EQU <_MessageBoxA@16>
MessageBox EQU <MessageBoxA>

ExitProcess EQU <_ExitProcess@4>

MB_OK equ 0

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib

.data

_message    db 'Hello world!',0
_title      db 'Hello',0

.code

start:

    MessageBox(0,ADDR _message,ADDR _title,MB_OK)

    ExitProcess(0)

END start


UASM v2.46, Dec 14 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

MessageBox.asm(24) : Error A2210: Syntax error: _MessageBox@16
MessageBox.asm(26) : Error A2210: Syntax error: _ExitProcess@4
MessageBox.asm: 28 lines, 1 passes, 5 ms, 0 warnings, 2 errors

johnsa

The equates are fine, you need a valid prototype though, so put this before the equates:


_MessageBox@16 PROTO :DWORD, :DWORD, :DWORD, :DWORD
_ExitProcess@4 PROTO :DWORD


Vortex

Hi johnsa,

Thanks. The version below works too :

.386
.model flat,stdcall
option casemap:none

MessageBoxA PROTO :DWORD, :DWORD, :DWORD, :DWORD
ExitProcess PROTO :DWORD

MessageBox EQU <MessageBoxA>

MB_OK equ 0

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib

.data

_message    db 'Hello world!',0
_title      db 'Hello',0

.code

start:

    MessageBox(0,ADDR _message,ADDR _title,MB_OK)

    ExitProcess(0)

END start