- New implementation of SendMessage, ReceiveMessage, ReplyMessage functions
[wine] / misc / toolhelp.c
1 /*
2  * Misc Toolhelp functions
3  *
4  * Copyright 1996 Marcus Meissner
5  */
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <ctype.h>
11 #include <assert.h>
12 #include "windows.h"
13 #include "win.h"
14 #include "winerror.h"
15 #include "process.h"
16 #include "tlhelp32.h"
17 #include "toolhelp.h"
18 #include "heap.h"
19 #include "k32obj.h"
20 #include "server.h"
21 #include "debug.h"
22
23
24 /* The K32 snapshot object object */
25 typedef struct
26 {
27     K32OBJ header;
28 } SNAPSHOT_OBJECT;
29
30 /* FIXME: to make this working, we have to callback all these registered 
31  * functions from all over the WINE code. Someone with more knowledge than
32  * me please do that. -Marcus
33  */
34 static struct notify
35 {
36     HTASK16   htask;
37     FARPROC16 lpfnCallback;
38     WORD     wFlags;
39 } *notifys = NULL;
40
41 static int nrofnotifys = 0;
42
43 static FARPROC16 HookNotify = NULL;
44
45 BOOL16 WINAPI NotifyRegister( HTASK16 htask, FARPROC16 lpfnCallback,
46                               WORD wFlags )
47 {
48     int i;
49
50     TRACE(toolhelp, "(%x,%lx,%x) called.\n",
51                       htask, (DWORD)lpfnCallback, wFlags );
52     if (!htask) htask = GetCurrentTask();
53     for (i=0;i<nrofnotifys;i++)
54         if (notifys[i].htask==htask)
55             break;
56     if (i==nrofnotifys) {
57         if (notifys==NULL)
58             notifys=(struct notify*)HeapAlloc( SystemHeap, 0,
59                                                sizeof(struct notify) );
60         else
61             notifys=(struct notify*)HeapReAlloc( SystemHeap, 0, notifys,
62                                         sizeof(struct notify)*(nrofnotifys+1));
63         if (!notifys) return FALSE;
64         nrofnotifys++;
65     }
66     notifys[i].htask=htask;
67     notifys[i].lpfnCallback=lpfnCallback;
68     notifys[i].wFlags=wFlags;
69     return TRUE;
70 }
71
72 BOOL16 WINAPI NotifyUnregister( HTASK16 htask )
73 {
74     int i;
75     
76     TRACE(toolhelp, "(%x) called.\n", htask );
77     if (!htask) htask = GetCurrentTask();
78     for (i=nrofnotifys;i--;)
79         if (notifys[i].htask==htask)
80             break;
81     if (i==-1)
82         return FALSE;
83     memcpy(notifys+i,notifys+(i+1),sizeof(struct notify)*(nrofnotifys-i-1));
84     notifys=(struct notify*)HeapReAlloc( SystemHeap, 0, notifys,
85                                         (nrofnotifys-1)*sizeof(struct notify));
86     nrofnotifys--;
87     return TRUE;
88 }
89
90 BOOL16 WINAPI StackTraceCSIPFirst(STACKTRACEENTRY *ste, WORD wSS, WORD wCS, WORD wIP, WORD wBP)
91 {
92     return TRUE;
93 }
94
95 BOOL16 WINAPI StackTraceFirst(STACKTRACEENTRY *ste, HTASK16 Task)
96 {
97     return TRUE;
98 }
99
100 BOOL16 WINAPI StackTraceNext(STACKTRACEENTRY *ste)
101 {
102     return TRUE;
103 }
104
105 /***********************************************************************
106  *           ToolHelpHook                             (KERNEL.341)
107  *      see "Undocumented Windows"
108  */
109 FARPROC16 WINAPI ToolHelpHook(FARPROC16 lpfnNotifyHandler)
110 {
111 FARPROC16 tmp;
112         tmp = HookNotify;
113         HookNotify = lpfnNotifyHandler;
114         /* just return previously installed notification function */
115         return tmp;
116 }
117
118
119 /***********************************************************************
120  *           CreateToolHelp32Snapshot                   (KERNEL32.179)
121  */
122 HANDLE32 WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) 
123 {
124     SNAPSHOT_OBJECT *snapshot;
125     struct create_snapshot_request req;
126     struct create_snapshot_reply reply;
127
128     TRACE( toolhelp, "%lx,%lx\n", flags, process );
129     if (flags & (TH32CS_SNAPHEAPLIST|TH32CS_SNAPMODULE|TH32CS_SNAPTHREAD))
130         FIXME( toolhelp, "flags %lx not implemented\n", flags );
131     if (!(flags & TH32CS_SNAPPROCESS))
132     {
133         SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
134         return INVALID_HANDLE_VALUE32;
135     }
136     /* Now do the snapshot */
137     if (!(snapshot = HeapAlloc( SystemHeap, 0, sizeof(*snapshot) )))
138         return INVALID_HANDLE_VALUE32;
139     snapshot->header.type = K32OBJ_TOOLHELP_SNAPSHOT;
140     snapshot->header.refcount = 1;
141
142     req.flags   = flags & ~TH32CS_INHERIT;
143     req.inherit = (flags & TH32CS_INHERIT) != 0;
144     CLIENT_SendRequest( REQ_CREATE_SNAPSHOT, -1, 1, &req, sizeof(req) );
145     if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ))
146     {
147         HeapFree( SystemHeap, 0, snapshot );
148         return INVALID_HANDLE_VALUE32;
149     }
150     return HANDLE_Alloc( PROCESS_Current(), &snapshot->header, 0, req.inherit, reply.handle );
151 }
152
153
154 /***********************************************************************
155  *              TOOLHELP_Process32Next
156  *
157  * Implementation of Process32First/Next
158  */
159 static BOOL32 TOOLHELP_Process32Next( HANDLE32 handle, LPPROCESSENTRY32 lppe, BOOL32 first )
160 {
161     struct next_process_request req;
162     struct next_process_reply reply;
163
164     if (lppe->dwSize < sizeof (PROCESSENTRY32))
165     {
166         SetLastError( ERROR_INSUFFICIENT_BUFFER );
167         ERR (toolhelp, "Result buffer too small\n");
168         return FALSE;
169     }
170     if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
171                                               K32OBJ_TOOLHELP_SNAPSHOT, 0 )) == -1)
172         return FALSE;
173     req.reset = first;
174     CLIENT_SendRequest( REQ_NEXT_PROCESS, -1, 1, &req, sizeof(req) );
175     if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
176     lppe->cntUsage            = 1;
177     lppe->th32ProcessID       = (DWORD)reply.pid;
178     lppe->th32DefaultHeapID   = 0;  /* FIXME */ 
179     lppe->th32ModuleID        = 0;  /* FIXME */
180     lppe->cntThreads          = reply.threads;
181     lppe->th32ParentProcessID = 0;  /* FIXME */
182     lppe->pcPriClassBase      = reply.priority;
183     lppe->dwFlags             = -1; /* FIXME */
184     lppe->szExeFile[0]        = 0;  /* FIXME */
185     return TRUE;
186 }
187
188
189 /***********************************************************************
190  *              Process32First    (KERNEL32.555)
191  *
192  * Return info about the first process in a toolhelp32 snapshot
193  */
194 BOOL32 WINAPI Process32First(HANDLE32 hSnapshot, LPPROCESSENTRY32 lppe)
195 {
196     return TOOLHELP_Process32Next( hSnapshot, lppe, TRUE );
197 }
198
199 /***********************************************************************
200  *              Process32Next   (KERNEL32.556)
201  *
202  * Return info about the "next" process in a toolhelp32 snapshot
203  */
204 BOOL32 WINAPI Process32Next(HANDLE32 hSnapshot, LPPROCESSENTRY32 lppe)
205 {
206     return TOOLHELP_Process32Next( hSnapshot, lppe, FALSE );
207 }