Which I don;t know of a way to do, so, I want to be able to launch the
process that destroys foo.exe such that foo.exe a) launches the uninstaller
program, and then b) foo.exe shuts down, and then c) the uninstaller program
deletes foo.exe, where, the uninstaller is something like a windows INF
script being run with rundll32. Basically I want to be able to remove every
last trace of foo from the system, and he's the guy that, when running,
knows when it's time to do so.
Any pointers are appreciated.
thx.
-Mark
--
Carey Gregory
First, write an extra program: "waitmutex.exe".
This program simply waits until the mutex named in the first command line
parameter is released, then sleeps for x seconds (you never know the program
is still running after releasing the mutex), and then exits
In your "real" program, you do this:
1. Create a mutex, and grab it
2. Create a temporary .BAT file, with three lines:
waitmutex whatever_unique_name_you_came_up_with
del waitmutex.exe
del realprog.exe
del %0.bat
3. Start the command processor in a hidden window, and tell it to execute
(with /C) the .BAT file you created.
4. Do whatever your "real" program does
5. Release the mutex
6. Exit
This works on most OS'es (I think):
http://www.microsoft.com/msj/0198/Win320198.htm
Chris King reported this about it (to get it to work on his system):
"However, I found I needed a Sleep() or WaitForInputIdle() after the
CreateProcess() call to allow the second instance to start correctly before
I CloseHandle()'d the first instance.
Luc
"Mark Meyers" <m...@ipass.net> wrote in message
news:O#AHCUUaAHA.1332@tkmsftngp05...
Cheers,
Guillaume.
"Carey Gregory" <sp...@nugenesis.spam.com> wrote in message
news:7c6t3t4hd1v6ror36...@4ax.com...
[rename]
nul=c:\snafu\foo.exe
nul=c:\foo\bar.exe
In NT-family, you call MoveFileEx() with a null second argument and the
MOVEFILE_DELAY_UNTIL_REBOOT flag.
--
Neil J. Rubenking
Contributing Technical Editor
PC Magazine
>But then how do you delete foo2.exe? ;)
Hey, he only asked how to delete foo.exe. Please see the cashier on
the way out. ;-)
--
Carey Gregory
> I'm wondering if there's a sure way to have a process running,
> c:\foo.exe that could then delete c:\foo.exe
It's _NT only_ pascal (Delphi) example.
--
WBR, LVT
--------------------------------------------------------
program Project1;
{$APPTYPE CONSOLE}
uses
windows,
sysutils;
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
cmdLine: String;
hprocess: THandle;
begin
if ParamStr(1) = '/del' then
begin
hprocess := OpenProcess(PROCESS_ALL_ACCESS, False, StrToInt(ParamStr(2)));
WaitForSingleObject(hprocess, INFINITE);
DeleteFile(PChar(ParamStr(3)));
ExitProcess(0);
end;
CopyFile(PChar(ParamStr(0)), 'tmp.exe', False);
if CreateFile(PChar('tmp.exe'),
GENERIC_READ,
FILE_SHARE_READ,
nil,
OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE,
0)= INVALID_HANDLE_VALUE then
ExitProcess(1);
cmdline := Format('tmp.exe /del %d "%s"', [GetCurrentProcessID, ParamStr(0)]);
FillChar(StartInfo, SizeOf(StartInfo), 0);
StartInfo.cb:=SizeOf(StartInfo);
if CreateProcess ( nil,
PChar(cmdLine),
nil,
nil,
false,
0,
nil,
nil,
StartInfo,
ProcInfo ) then
begin
CloseHandle(ProcInfo.hThread);
CloseHandle(ProcInfo.hProcess);
Writeln('Press any key for delete..');
Readln;
end
else
ExitProcess(2);
end.
Gary
#include <windows.h>
int main(int argc, char *argv[])
{
HMODULE module = GetModuleHandle(0);
CHAR buf[MAX_PATH];
GetModuleFileName(module, buf, sizeof buf);
CloseHandle(HANDLE(4));
ULONG p = ULONG(module) + 1;
__asm {
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push p
push DeleteFile
push FreeLibrary
ret
}
return 0;
}
dave
p.s. Your code seems to lack
error handling :-)
--
To reply by mail, replace 'z' by 's'
"Gary Nebbett" <gary.n...@syngenta.com> wrote in message
news:91q3cn$v8n$1...@novalfsmtp1.novsvcs.net...
Hello Dave,
The rather cavalier reasoning and observations that led to
the hard-coded value is that when creating a new process,
the first handle that is added to the handle table is that
of the executable image section and there is no user-mode
variable that holds this value (and therefore the handle
will presumably never be closed). This is of course just an
artifact of the implementation.
Never having worked on a safety critical system, I am rather
in the habit of just letting a program crash and then
analysing the remains :-)
Gary
Sent via Deja.com
http://www.deja.com/
"Luc Kumps" <NOkum...@pandora.be> wrote in message
news:yHE%5.12797$Ww.2...@afrodite.telenet-ops.be...
return 0;
}
What do you get from pushing all those params on the stack before returning-
who reads them?
(Sorry, not an experienced assembly coder)
-Mark
<gary.n...@syngenta.com> wrote in message
news:91qlsd$6hm$1...@nnrp1.deja.com...
When the ginal RET executes, it "returns" to the address on the top of the
stack, which is FreeLibrary.
The FreeLibrary finds these two things on the stack:
1. The address to return to (=DeleteFile)
2. The value of p, which is the parameter passed to FreeLibrary
When FreeLibrary returns, it returns to DeleteFile, which finds on the
stack:
1. Return address=ExitProcess
2. Parameter = eax = address of buf = name of file to delete
When DeleteFile returns, it returns to ExitProcess, which finds on the
stack:
1. Return address 0 (never used)
2. Value 0 (exit code of process)
Luc
"Mark Meyers" <m...@ipass.net> wrote in message
news:e9dnsnraAHA.1852@tkmsftngp02...
The 'ret' pops an address from the stack and 'returns'
to it, so it actually calls FreeLibrary. FreeLibrary returns
to DeleteFile, DeleteFile returns to ExitProcess,
ExitProcess doesn't return.
> int main(int argc, char *argv[])
> {
> __asm {
> lea eax, buf
> push 0 // arg for ExitProcess
> push 0 // return from ExitProcess call (not used)
> push eax // arg for DeleteFile
> push ExitProcess // return from DeleteFile call
> push p // arg for FreeLibrary
> push DeleteFile // return from FreeLibrary call
> push FreeLibrary // return from here
> ret
> }
>
> return 0;
> }
>
In other words Gary's caused a sequence of functions
to get called, by setting up the stack, without ever
touching the code section again (which is just as well
since it presumably vanishes half-way through the
sequence).
What a perversion (and I mean that as a compliment :-)
dave
So there's something other than handle #4
being open which is keeping the code
around? (I presume FreeLibrary is merely
Win32ese for FreeImageFileSections, there's nothing
particularly libroid about it).
dave
--
To reply by mail, replace 'z' by 's'
"Gary Nebbett" <gary.n...@syngenta.com> wrote in message
news:91q3cn$v8n$1...@novalfsmtp1.novsvcs.net...
Never mind, I read the Win32 documentation
where it mentions reference counts.
"dave porter" <por...@mangozoft.com> wrote in message
news:91r679$6si$1...@bob.news.rcn.net...
That is an interesting question. If you look at figure 7-24 in
the 3rd edition of Inside Microsoft Windows 2000, there are two
things that keep the whole mesh of data structures (including
the file object for the executable file) alive: the VAD and the
section object. CloseHandle(HANDLE(4)) deletes the section
object and UnmapViewOfFile(module) deletes the VAD.
In the program that I posted, I used FreeLibrary(ULONG(module) +
1) because I had previously observed some undocumented behaviour
of FreeLibrary that caused it to ignore reference counts and
simply unmap a library if the low bit of the module was set. On
reflection, I think that it would be better to use
UnmapViewOfFile directly. Attached is an updated (and slightly
shorter!) version of the program.
Gary
#include <windows.h>
int main(int argc, char *argv[])
{
HMODULE module = GetModuleHandle(0);
CHAR buf[MAX_PATH];
GetModuleFileName(module, buf, sizeof buf);
CloseHandle(HANDLE(4));
__asm {
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push UnmapViewOfFile
ret
}
return 0;
This is a truly remarkable hack. One of the most clever pieces of code I've
ever seen.
Alas, this and the version posted previously work only on NT/2000. Has
anyone come up with a similar trick for 95/98/Me? If not, maybe I'll give it
a crack when I get some time...
-Mike
<gary.n...@syngenta.com> wrote in message
news:91shos$o3q$1...@nnrp1.deja.com...
on a probably related (ie., DeleteFile after UnmapViewOfFile) topic,
how can one find which process uses some file (to be deleted)? eg.:
| C:\>del /q /s "C:\WINNT\Profiles\george\Temporary Internet Files"
| C:\WINNT\Profiles\george\Temporary Internet
Files\Content.IE5\index.dat
| The process cannot access the file because
| it is being used by another process.
(after, obviously, one exits IE itself -- to purge its 'temp' stuff)
there must be some dll still laying around which *uses* index.dat:
which one?
thanks,
george
> on a probably related (ie., DeleteFile after UnmapViewOfFile) topic,
> how can one find which process uses some file (to be deleted)?
Let me take a guess. I'll bet www.sysinternals.com has something for this...
Yup, they do! HandleEx:
http://www.sysinternals.com/ntw2k/freeware/handleex.shtml
-Mike