News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

TaskDialog

Started by guga, April 10, 2025, 07:17:48 AM

Previous topic - Next topic

sinsi

Quote from: guga on April 16, 2025, 09:38:06 PMNow that we managed to work this without manifest embedded on the resource section
Are you sure? If I omit the manifest I get an error
You cannot view this attachment.

guga

#46
Quote from: sinsi on April 16, 2025, 11:18:52 PM
Quote from: guga on April 16, 2025, 09:38:06 PMNow that we managed to work this without manifest embedded on the resource section
Are you sure? If I omit the manifest I get an error
You cannot view this attachment.


Hi Sinsi. That´s odd. I mean not using manifest on the app that is calling the dll. See reply 16.

You need to find in which directory inside WinSXS contains comctl32 with this Api and uses LoadLibrary to call it.

On my case it is located at: C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.4355_none_a865f0c28672571c\COMCTL32.dll

See here:

https://masm32.com/board/index.php?topic=12688.15
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

TimoVJL

external manifest file may help.
tdi.exe.manifest
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
</assembly>
RosAsm seems to be problem in these cases, if link.exe isn't used with object code.


May the source be with you

adeyblue

Alternatively:
    PCWSTR pFile = L"C:\\Windows\\WindowsShell.manifest"; // this exists from at least Win7 to Win11
    ACTCTX ctx = {sizeof(ctx)};
    HANDLE hAct;
    ULONG_PTR cookie;
    ctx.lpSource = pFile;
    hAct = CreateActCtx(&ctx);
    if(hAct != INVALID_HANDLE_VALUE)
    {
        ActivateActCtx(hAct, &cookie);
        // great stuff
    }
After ActivateActCtx LoadLibrary(comctl32) will be the 6.0 version. and you can GetProcAddress what you want.
Any non-GetProcAddress comctl32 functions will still go to the 5.82 version. You have to use an exe manifest to redirect those.

guga

Quote from: TimoVJL on April 17, 2025, 03:08:54 AMexternal manifest file may help.
tdi.exe.manifest
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
</assembly>
RosAsm seems to be problem in these cases, if link.exe isn't used with object code.




yes, but there ´s no link.exe in RosAsm. Since it doesn´t contains manifest on itself, when it tries to assemble (link) dlls, it uses loadlibrary to get the proper addresses and without the manifest, it will locate comctl with the older version and not the new one required by the manifest. I´ll fix that later .

I tried to port my example without manifest, but i don't remember what is the proper masm syntax. Qeditor keeps showing an error "C:\masm32\examples\TaskDialog\TaskDialog.asm(96) : error A2206: missing operator in expression"

This line is related to:
   TaskDialogConfig    TASKDIALOGCONFIG \
                        <96, 0, 0, 0, TDCBF_YES_BUTTON+TDCBF_NO_BUTTON, \
                         OFFSET Sz_WindowTitle, TD_SHIELD_ICON, OFFSET Sz_MainInstruction, \
                         OFFSET Sz_Content, 0, 0, 0, 3, OFFSET RadioButtons, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>

I did this:

; #########################################################################

      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

; #########################################################################



      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\gdi32.inc
     

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


; Prototype for TaskDialogIndirect
TaskDialogIndirect PROTO :DWORD, :DWORD, :DWORD, :DWORD

    .data
TDCBF_OK_BUTTON equ 1
TDCBF_YES_BUTTON equ 2
TDCBF_NO_BUTTON equ 4
TDCBF_CANCEL_BUTTON equ 8
TDCBF_RETRY_BUTTON equ 16
TDCBF_CLOSE_BUTTON equ 32

TD_WARNING_ICON equ 0xFFFFh
TD_ERROR_ICON equ 0xFFFEh
TD_INFORMATION_ICON equ 0xFFFDh
TD_SHIELD_ICON equ 0xFFFCh


   
; Structure definitions
TASKDIALOG_BUTTON struct
    nButtonID      DWORD ?
    pszButtonText  DWORD ? ; Pointer to Unicode string
TASKDIALOG_BUTTON ends

TASKDIALOGCONFIG struct
    cbSize              DWORD 0
    hwndParent          HWND 0
    hInstance           HINSTANCE 0
    dwFlags             DWORD 0
    dwCommonButtons     DWORD 0
    pszWindowTitle      DWORD 0
    hMainIcon           DWORD 0
    pszMainInstruction  DWORD 0
    pszContent          DWORD 0
    cButtons            DWORD 0
    pButtons            DWORD 0
    nDefaultButton      DWORD 0
    cRadioButtons       DWORD 0
    pRadioButtons       DWORD 0
    nDefaultRadioButton DWORD 0
    pszVerificationText DWORD 0
    pszExpandedInformation DWORD 0
    pszExpandedControlText DWORD 0
    pszCollapsedControlText DWORD 0
    hFooterIcon         DWORD 0
    pszFooter           DWORD 0
    pfCallback          DWORD 0
    lpCallbackData      DWORD 0
    cxWidth             DWORD 0
TASKDIALOGCONFIG ends

.data
    hInstance           DWORD 0
    hDll                DWORD 0
    hTaskDialogIndirect DWORD 0
    nButtonPressed      DWORD 0

    ; Unicode strings
    Sz_Radio1           TCHAR "Lets do Item1", 0, 0
    Sz_Radio2           TCHAR "Or maybe 2", 0, 0
    Sz_Radio3           TCHAR "Super secret option", 0, 0
    Sz_MainInstruction  TCHAR "You're about to do something stupid.", 0, 0
    Sz_Content          TCHAR "Are you absolutely sure you want to continue with this really bad idea?", 0, 0
    Sz_WindowTitle      TCHAR "cTaskDialog Project", 0, 0
    Sz_Comctl32         db 'COMCTL32.dll', 0
    Sz_TaskDialogIndirect db "TaskDialogIndirect", 0

    ; Radio button array
    RadioButtons        TASKDIALOG_BUTTON \
                        <110, OFFSET Sz_Radio1>,
                        <111, OFFSET Sz_Radio2>,
                        <112, OFFSET Sz_Radio3>

    ; TaskDialog configuration
   TaskDialogConfig    TASKDIALOGCONFIG \
                        <96, 0, 0, 0, TDCBF_YES_BUTTON+TDCBF_NO_BUTTON, \
                         OFFSET Sz_WindowTitle, TD_SHIELD_ICON, OFFSET Sz_MainInstruction, \
                         OFFSET Sz_Content, 0, 0, 0, 3, OFFSET RadioButtons, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>


.code
start:
    ; Get module handle
    invoke GetModuleHandle, NULL
    mov hInstance, eax

    ; Load COMCTL32.dll
    invoke LoadLibrary, OFFSET Sz_Comctl32
    mov hDll, eax

    ; Get TaskDialogIndirect address
    invoke GetProcAddress, hDll, OFFSET Sz_TaskDialogIndirect
    mov hTaskDialogIndirect, eax

    ; Call TaskDialogIndirect
    invoke TaskDialogIndirect, OFFSET TaskDialogConfig, ADDR nButtonPressed, 0, 0

    ; Exit process
    invoke ExitProcess, 0

end start


Btw, i´m quite sure it won´t work at
    invoke TaskDialogIndirect, OFFSET TaskDialogConfig, ADDR nButtonPressed, 0, 0
because TaskDialogIndirect should be replace by the pointer at eax

But, as i dont remember how to use invoke on such situations, i´m posting here my attempt to port this to masm
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

TimoVJL

An external manifest file don't need link.exe
I haven't tested, how it works with dynamic loading dlls.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#pragma comment(lib, "user32.lib")

void __cdecl WinMainCRTStartup(void)
{
    TCHAR szTmp[260];
    HMODULE hDll = LoadLibrary(TEXT("Comctl32.dll"));
    GetModuleFileName(hDll, szTmp, sizeof(szTmp));
    MessageBox(0, szTmp, TEXT("Info"), MB_OK);
    ExitProcess(0);
}
UAsm example was build with commands:
uasm64.exe -c -win64 TestTaskDialog2MS.asm
link.exe TestTaskDialog2MS.obj -subsystem:windows -manifest:embed
May the source be with you

zedd151

#51
Quote from: guga on April 17, 2025, 04:04:38 AMI did this:


With this test code:


    include \masm32\include\masm32rt.inc

.data
    hInstance          DWORD 0
    hDll                DWORD 0
    hTaskDialogIndirect DWORD 0
    Sz_Comctl32        db 'COMCTL32.dll', 0
    Sz_TaskDialogIndirect db "TaskDialogIndirect", 0

.code
start:
    invoke InitCommonControls
    ; Get module handle
    invoke GetModuleHandle, NULL
    mov hInstance, eax

    ; Load COMCTL32.dll
    invoke LoadLibrary, addr Sz_Comctl32
    mov hDll, eax

    ; Get TaskDialogIndirect address
    invoke GetProcAddress, hDll, addr Sz_TaskDialogIndirect
    mov hTaskDialogIndirect, eax

    ; Exit process
    invoke ExitProcess, 0

end start

I am getting this for "TaskDialogIndirect" using link from the masm32 SDK...
ERROR_PROC_NOT_FOUND (0000007F)
as shown in ollydbg

I tried with and without "invoke InitCommonControls" there is a manifest in the .rc file.

I had to dig into WinSxS for a version that was 32 bit, and had that function.
\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.4355_none_a865f0c28672571c\comctl32.dll
    include \masm32\include\masm32rt.inc

.data
    hInstance              dd 0
    hDll                    dd 0
    hTaskDialogIndirect    dd 0
    Sz_Comctl32            db ".\COMCTL32.dll", 0
    Sz_TaskDialogIndirect  db "TaskDialogIndirect", 0

.CODE
start:
    ; Get module handle
    invoke GetModuleHandle, 0
    mov hInstance, eax

    ; Load COMCTL32.dll
    invoke LoadLibrary, addr Sz_Comctl32
    mov hDll, eax

    ; Get TaskDialogIndirect address
    invoke GetProcAddress, hDll, addr Sz_TaskDialogIndirect
    mov hTaskDialogIndirect, eax

    ; Exit process
    invoke ExitProcess, 0

end start

Then success it found the function, and it loaded. No manifest.  :smiley:  While still using ml & link from the Masm32 SDK.  That being said, I obviously did not test whether or not TaskDialogIndirect would actually create the TaskDialog, without a manifest. I am heading outside to do more chores. When I get back inside, I'll try to create a TaskDialog ...  :azn:

I copied the .dll to my desktop in a folder where I have the test program.
Attached is the second test, where it was a success in loading the function. (but obviously  the .dll is not attached)

guga

Quote from: TimoVJL on April 17, 2025, 04:13:29 AMAn external manifest file don't need link.exe
I haven't tested, how it works with dynamic loading dlls.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#pragma comment(lib, "user32.lib")

void __cdecl WinMainCRTStartup(void)
{
    TCHAR szTmp[260];
    HMODULE hDll = LoadLibrary(TEXT("Comctl32.dll"));
    GetModuleFileName(hDll, szTmp, sizeof(szTmp));
    MessageBox(0, szTmp, TEXT("Info"), MB_OK);
    ExitProcess(0);
}
UAsm example was build with commands:
uasm64.exe -c -win64 TestTaskDialog2MS.asm
link.exe TestTaskDialog2MS.obj -subsystem:windows -manifest:embed

Hi Timo. I now, but you didn´t get it. RosAsm won´t assemble any file, with an external manifest because it will try to find the address but Rosasm.exe itself does not uses manifest in it´s resource section and neither an external manifest for RosAsm itself from where it could bypass the older dll versions. In time i´ll try to update this and make it assemble files with and without manifest.

Although you can insert a manifest in the resources section of the file you arre trying to assemble with RosAsm, if the target dll points to an Api (non existent in older versions) that are being tried to load by RosAsm itself in order to it retrieve the address, then it won´t work. This taskdialog issue is good, so i can try fixing it in the future. I never had such problems before, because all Apis whose dlls uses uses manifests, where also existed on non-manifest (older versions) that was what rosasm uses to assemble.

At then end, the thread turned to be good for me to fix one more thing in RosAsm in the future.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

Quote from: zedd151 on April 17, 2025, 04:20:09 AM
Quote from: guga on April 17, 2025, 04:04:38 AMI did this:


With this test code:


    include \masm32\include\masm32rt.inc

.data
    hInstance          DWORD 0
    hDll                DWORD 0
    hTaskDialogIndirect DWORD 0
    Sz_Comctl32        db 'COMCTL32.dll', 0
    Sz_TaskDialogIndirect db "TaskDialogIndirect", 0

.code
start:
    invoke InitCommonControls
    ; Get module handle
    invoke GetModuleHandle, NULL
    mov hInstance, eax

    ; Load COMCTL32.dll
    invoke LoadLibrary, addr Sz_Comctl32
    mov hDll, eax

    ; Get TaskDialogIndirect address
    invoke GetProcAddress, hDll, addr Sz_TaskDialogIndirect
    mov hTaskDialogIndirect, eax

    ; Exit process
    invoke ExitProcess, 0

end start

I am getting this for "TaskDialogIndirect" using link from the masm32 SDK...
ERROR_PROC_NOT_FOUND (0000007F)
as shown in ollydbg

I tried with and without "invoke InitCommonControls" there is a manifest in the .rc file.

I had to dig into WinSxS for a verion that was 32 bit, and had that function.
\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.4355_none_a865f0c28672571c\comctl32.dll
    include \masm32\include\masm32rt.inc

.data
    hInstance              dd 0
    hDll                    dd 0
    hTaskDialogIndirect    dd 0
    Sz_Comctl32            db ".\COMCTL32.dll", 0
    Sz_TaskDialogIndirect  db "TaskDialogIndirect", 0

.CODE
start:
    ; Get module handle
    invoke GetModuleHandle, 0
    mov hInstance, eax

    ; Load COMCTL32.dll
    invoke LoadLibrary, addr Sz_Comctl32
    mov hDll, eax

    ; Get TaskDialogIndirect address
    invoke GetProcAddress, hDll, addr Sz_TaskDialogIndirect
    mov hTaskDialogIndirect, eax

    ; Exit process
    invoke ExitProcess, 0

end start

Then success it found the function, and it loaded. No manifest.  :smiley:  While still using ml & link from the Masm32 SDK.  That being said, I obviously did not test whether or not TaskDialogIndirect would actually create the TaskDialog, without a manifest. I am heading outside to do more chores. When I get back inside, I'll try to create a TaskDialog ...  :azn:

I copied the .dll to my desktop in a folder where I have the test program.
Attached is the second test, where it was a success in loading the function. (but obviously  the .dll is not attached)

Great work ! :thumbsup:  :thumbsup:  :thumbsup:
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

TimoVJL

External manifest is just a xml-file with same name as exe and .manifest inserted to it's name.

So if you make an program named test.exe, then copy manifest template file to test.exe.manifest
May the source be with you

guga

Quote from: TimoVJL on April 17, 2025, 05:52:26 AMExternal manifest is just a xml-file with same name as exe and .manifest inserted to it's name.

So if you make an program named test.exe, then copy manifest template file to test.exe.manifest


You mean, if i create a RosAsm.exe.manifest, put it onto the same folder as the main RosAsm.exe, it will then assemble other files with newer versions of these dlls ? I´ll give a try later. Never did that before.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

Quote from: TimoVJL on April 17, 2025, 05:52:26 AMExternal manifest is just a xml-file with same name as exe and .manifest inserted to it's name.

So if you make an program named test.exe, then copy manifest template file to test.exe.manifest


Great tip. Worked. It assembled the file. - Not working because i didn´t included the manifest file (neither external or internal), but, it is assembling. The problem with this manifest as a external file, is that it changes

the interface of RosAsm. It became a bit weird (although reveled some more issues that may requires fixes)
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

TimoVJL

Every exe need manifest file, if they need newer 6.0 version of comctl32.dll

Rosasm.exe itself can use 6.0 version dll, if have manifest-file in same folder.

May the source be with you

guga

Worked. Now with the manifest embedded in the executable. Too much trouble for a simple thing. I´ll need to review those issues in RosAsm once i have more free time. I don´t like those manifest things, but, it indeed may be helpfull for others.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

zedd151

Quote from: guga on April 17, 2025, 06:19:29 AMWorked.
:thumbsup:  :thumbsup:


Although the text "You're about to do something stupid." was somewhat alarming.  :joking:  :joking:
Of course I tried all 3 options, regardless.  :tongue:

I will still try to make my version.  :azn:  It'll give me something to do later this evening.


@Timo, good tip on the "*.manifest" file. I had seen those files in windows folders in various places, but didn't know how/when they would or could be useful in assembly.  :thumbsup:  :thup:  :thumbsup:  :thup:  :biggrin:   I'll have to explore this new knowledge further at another time.