News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Installers and Uninstallers

Started by ossama, December 29, 2007, 04:27:26 PM

Previous topic - Next topic

ossama

hello,this topic is dedicated to how to write installers and uninstallers in masm
it is the place where you can post your ideas and methods .
i created this topic because i had asked before about "how to use big files in rersources" and that topic was "deviate" to installers and uninstallers.
i had searched the web and i find many tips about how to install/uninstall files but some of theme run in a version of windows and does not run in other version,and and and....
your ideas here can contribute to a project of install/uninstall manager that i am  working on,i will post the code here and it is welcome of comments and sujggestions and optimizations.
regards OSSAMA

ossama

how can my installer replace files that are in use by other programs,in fact i have a dll that is shared between many programs and my setup needs to replace that dll, how can i do it ? (without terminating programs using that DLL if it is possible)

thank you in advance.

donkey

Quote from: ossama on December 30, 2007, 09:01:09 AM
how can my installer replace files that are in use by other programs,in fact i have a dll that is shared between many programs and my setup needs to replace that dll, how can i do it ? (without terminating programs using that DLL if it is possible)

thank you in advance.

MoveFileEx
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

ossama

hi donkey,
i know that MoveFileEx will replace files after reboot.

ossama

donkey,
do you mean using MoveFileEx with MOVEFILE_REPLACE_EXISTING flag?

TNick

Quote from: ossama on December 30, 2007, 10:03:56 AM
hi donkey,
i know that MoveFileEx will replace files after reboot.
I guess that is what donkey suggests. Use MoveFileEx then, when installation is completed, tell the user that he/she needs "to restart the computer in order to complete the instalation."

Nick

donkey

Quote from: TNick on December 30, 2007, 02:22:32 PM
Quote from: ossama on December 30, 2007, 10:03:56 AM
hi donkey,
i know that MoveFileEx will replace files after reboot.
I guess that is what donkey suggests. Use MoveFileEx then, when installation is completed, tell the user that he/she needs "to restart the computer in order to complete the instalation."

Nick

That's what I meant, sorry I thought it was self evident that you would have to do that. I am pretty sure that there must be another way to do it but I don't know what it is. XP seems to be capable of modifying system files and running DLLs without a reboot but I suspect this behavior is undocumented but the security implications are staggering so I am not sure if you could do it from protected mode.

Anyway, it seems impolite to me to not ask for a reboot, it at least warns the user that a critical file will be updated or changed.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

ossama

Quote from: donkey on December 30, 2007, 04:59:36 PM
XP seems to be capable of modifying system files and running DLLs without a reboot but I suspect this behavior is undocumented but the security implications are staggering so I am not sure if you could do it from protected mode.

yes, replaceing DLLs and other files without rebooting the system is the best solution, i wonder why microsoft do not make informations like this public.

donkey

Quote from: ossama on December 30, 2007, 05:05:04 PM
Quote from: donkey on December 30, 2007, 04:59:36 PM
XP seems to be capable of modifying system files and running DLLs without a reboot but I suspect this behavior is undocumented but the security implications are staggering so I am not sure if you could do it from protected mode.

yes, replaceing DLLs and other files without rebooting the system is the best solution, i wonder why microsoft do not make informations like this public.

Well, it is documented as side by side assembly, but not which system files are set up for it.

"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

u

Installers... just a few notes of my experience:
instead of putting the data in resource-files, just concatenate right after the .exe file. In a custom simple .zip-like file. And put the offset of the data right into the last 4 bytes.
For this, you need to make two separate executables, of course - the installer itself, and the installation-packer. The packer compresses and puts all data-files into a memory-chunk, then concatenates the installer.exe and this data-chunk to produce final.exe . Of course, you'd also add two CRC values in any way/place you want - one to detect whether the whole file has been downloaded completely, and the other - if the file was downloaded correctly.

Then, there are two ways to handle errors during the installation :
1) probe first whether you have read/write permission to the target Registry keys and file-system directories (as well as amount of free space)
2) make a simple "undo-system". At it's simplest, it's a stack of variable-sized command-arrays [ that have been executed successfully ] . On failure on some task, you simply roll-back, calling the undoing versions of those commands. (a CreatedFile command will do a DeleteFile). This can become quite elegant, like CreateFolder() being discarded if the folder already existed, or SetRegistryKeyValue remembering the previous value if that key already existed.

In the data-chunk you concatenate to installer.exe also add an uninstall.exe . When run without special parameters, it will copy itself to the %TEMP% folder, run that copy with special parameters and immediately exit. When run with those special parameters (you define them, of course) , uninstall.exe will sleep for 1 second, probe whether it can delete the files, and repeat several times until it can [ but do add an iteration-count limit ].  Its first attempt could also be to find and stop the main (real, useful) executable of your app. Deleting files, folders and registry-keys can be done in a predetermined way. But to be even more intelligent, why not make it simply "undo" the installation, via those command-arrays :) . To do this, use again file-concatenation. But since this data is dependent on this PC's previous settings/state, this concatenation will be done only right after the installation on this PC, by the installer itself.
After the TEMP\uninstall.exe completes all tasks and notifies the user of it, it suicides in one of the official Windows ways [making Windows delete this .exe after it exits]. We moved uninstall.exe to TEMP just in case Windows (old or some future versions) refuse to help in that last deletion. 
Please use a smaller graphic in your signature.

ossama

hi Ultrano,thank you for the topic,
would you explain the section of "arrray of commands" how it works.
regards OSSAMA

u

here are examples of bloated commands:


CMD_TYPE__CREATE_FILE equ 0
CMD_TYPE__DELETE_FILE equ 1
CMD_TYPE__CREATE_FOLDER equ 2
CMD_TYPE__DELETE_FOLDER equ 3
CMD_TYPE__CREATE_REGVALUE_DWORD equ 4
CMD_TYPE__DELETE_REGVALUE_DWORD equ 5

CmdBaseInfo struct
CmdType db ? ; one of the above CMD_TYPE__***
CmdSize dd ? ; total size of the encapsulating struct
CmdBaseInfo ends

CmdCreateFile struct
cmd CmdBaseInfo <> ; CmdType=CMD_TYPE__CREATE_FILE, CmdSize=sizeof CmdCreateFile

FileName db 260 dup (?)
CmdCreateFile ends

CmdDeleteFile struct
cmd CmdBaseInfo <> ; CmdType=CMD_TYPE__DELETE_FILE, CmdSize=sizeof CmdDeleteFile

FileName db 260 dup (?)
CmdDeleteFile ends

CmdCreateRegValueDword struct
cmd CmdBaseInfo <> ; CmdType=CMD_TYPE__CREATE_REGVALUE_DWORD

RegKeyName db 200 dup (?)
RegKeyValueName db 60 dup (?)

RegKeyValue dd ?
CmdCreateRegValueDword ends

...

ExecuteCommand proc pCmd
mov ecx,pCmd
mov eax,[ecx].CmdBaseInfo.CmdType

.if eax==CMD_TYPE__CREATE_FILE
invoke MyCreateFile,addr [ecx].CmdCreateFile.FileName
.else if eax==CMD_TYPE__DELETE_FILE
invoke MyDeleteFile,addr [ecx].CmdDeleteFile.FileName
.else if .......
.....
ret
ExecuteCommand endp


Obviously the bloat is only because we use whole 260 bytes even if a file-name takes 20 bytes. These commands will be written on disk, (concatenating after uninstall.exe) so removing the bloat is necessary. Fortunately removing the bloat is easy.

An array of those commands, - what I meant was a custom stack of dwords, each being a pointer to an executed instance of a command-struct. We push the "undoing versions" of executed commands on this stack, and on failure/uninstall we pop to execute.
Please use a smaller graphic in your signature.

Jackal

i like this method ultrano mentioned but it seems like a lot more work than i did. Since mine is for my personal use and i have compression and not only that is used for my masm apps the files are always pretty small so i put them in the resource file and when i compile my installed i just put and array of the files in my data sections. The code runs a loop to install all the files in that array.


SavePath db "P6 Live Map Manager.exe",0
SavePath2 db "p6lmm.dat",0
Saves dd " ", " ", SavePath, SavePath2, 0
AppFileCount dd 2

2 RCDATA DISCARDABLE "res\Live_Map_Manager_c.exe"
3 RCDATA DISCARDABLE "res\p6lmm_c.dat"


        push edi
        push esi
        mov esi, AppFileCount
        mov FileNum, 2
       @@:
        test esi, esi
        jz @F
         mov edi, FileNum
         Invoke WriteAppFile, edi, [Saves+edi*4]
         add FileNum, 1
        SUB esi, 1
        jmp @B
       @@:
        pop esi
        pop edi


Also i didnt do an undo if they cancel. As they go through the installer i just store all the info in variables and when they are done they can click install and i disable the back button. When they click on install it goes through and craetes all folders, files, links and registry keys. The uninstall i did different too. The way i did is it when the user runs the exe and says yes they want to unistall it creates a cloned process of the exe and then exits. The cloned process waits for the exe to exit and then goes through and does all the removals and when its done closes its own process. This avoids using windows to remove the final app or every creating a temp file.

ossama

QuoteThe way i did is it when the user runs the exe and says yes they want to unistall it creates a cloned process of the exe and then exits. The cloned process waits for the exe to exit and then goes through and does all the removals and when its done closes its own process. This avoids using windows to remove the final app or every creating a temp file.

hi,
would you post the code of the above section.
and does it work in both win 9x and xp?

Jackal

if a mod says that it is ok to post this type of code then yes i will. I have not tested it on 9x but it does work on xp and vista.