Use emergency TEB selector to avoid debugger crashes when stepping
[wine/multimedia.git] / files / change.c
blob7a09e5ce37354ef74cd669d5e596bd129b1665a9
1 /*
2 * Win32 file change notification functions
4 * Copyright 1998 Ulrich Weigand
5 */
7 #include <errno.h>
8 #include <assert.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <time.h>
13 #include "windows.h"
14 #include "winbase.h"
15 #include "winerror.h"
16 #include "process.h"
17 #include "thread.h"
18 #include "heap.h"
19 #include "debug.h"
21 static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id );
22 static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id );
23 static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id );
24 static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id );
25 static void CHANGE_Destroy( K32OBJ *obj );
27 const K32OBJ_OPS CHANGE_Ops =
29 CHANGE_Signaled, /* signaled */
30 CHANGE_Satisfied, /* satisfied */
31 CHANGE_AddWait, /* add_wait */
32 CHANGE_RemoveWait, /* remove_wait */
33 NULL, /* read */
34 NULL, /* write */
35 CHANGE_Destroy /* destroy */
38 /* The change notification object */
39 typedef struct
41 K32OBJ header;
43 LPSTR lpPathName;
44 BOOL32 bWatchSubtree;
45 DWORD dwNotifyFilter;
47 THREAD_QUEUE wait_queue;
48 BOOL32 notify;
50 } CHANGE_OBJECT;
52 /***********************************************************************
53 * CHANGE_Signaled
55 static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id )
57 CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
58 assert( obj->type == K32OBJ_CHANGE );
59 return change->notify;
62 /***********************************************************************
63 * CHANGE_Satisfied
65 * Wait on this object has been satisfied.
67 static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id )
69 assert( obj->type == K32OBJ_CHANGE );
70 return FALSE; /* Not abandoned */
73 /***********************************************************************
74 * CHANGE_AddWait
76 * Add thread to object wait queue.
78 static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id )
80 CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
81 assert( obj->type == K32OBJ_CHANGE );
82 THREAD_AddQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) );
85 /***********************************************************************
86 * CHANGE_RemoveWait
88 * Remove thread from object wait queue.
90 static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id )
92 CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
93 assert( obj->type == K32OBJ_CHANGE );
94 THREAD_RemoveQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) );
97 /****************************************************************************
98 * CHANGE_Destroy
100 static void CHANGE_Destroy( K32OBJ *obj )
102 CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
103 assert( obj->type == K32OBJ_CHANGE );
105 if ( change->lpPathName )
107 HeapFree( SystemHeap, 0, change->lpPathName );
108 change->lpPathName = NULL;
111 obj->type = K32OBJ_UNKNOWN;
112 HeapFree( SystemHeap, 0, change );
115 /****************************************************************************
116 * FindFirstChangeNotification32A (KERNEL32.248)
118 HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
119 BOOL32 bWatchSubtree,
120 DWORD dwNotifyFilter )
122 HANDLE32 handle;
123 CHANGE_OBJECT *change;
125 change = HeapAlloc( SystemHeap, 0, sizeof(CHANGE_OBJECT) );
126 if (!change) return INVALID_HANDLE_VALUE32;
128 change->header.type = K32OBJ_CHANGE;
129 change->header.refcount = 1;
131 change->lpPathName = HEAP_strdupA( SystemHeap, 0, lpPathName );
132 change->bWatchSubtree = bWatchSubtree;
133 change->dwNotifyFilter = dwNotifyFilter;
135 change->wait_queue = NULL;
136 change->notify = FALSE;
138 handle = HANDLE_Alloc( PROCESS_Current(), &change->header,
139 FILE_ALL_ACCESS /*FIXME*/, TRUE, -1 );
140 /* If the allocation failed, the object is already destroyed */
141 if (handle == INVALID_HANDLE_VALUE32) change = NULL;
142 return handle;
145 /****************************************************************************
146 * FindFirstChangeNotification32W (KERNEL32.249)
148 HANDLE32 WINAPI FindFirstChangeNotification32W( LPCWSTR lpPathName,
149 BOOL32 bWatchSubtree,
150 DWORD dwNotifyFilter)
152 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpPathName );
153 HANDLE32 ret = FindFirstChangeNotification32A( nameA, bWatchSubtree,
154 dwNotifyFilter );
155 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
156 return ret;
159 /****************************************************************************
160 * FindNextChangeNotification (KERNEL32.252)
162 BOOL32 WINAPI FindNextChangeNotification( HANDLE32 handle )
164 CHANGE_OBJECT *change;
166 SYSTEM_LOCK();
167 if (!(change = (CHANGE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(),
168 handle, K32OBJ_CHANGE,
169 0 /*FIXME*/, NULL )) )
171 SYSTEM_UNLOCK();
172 return FALSE;
175 change->notify = FALSE;
176 K32OBJ_DecCount( &change->header );
177 SYSTEM_UNLOCK();
178 return TRUE;
181 /****************************************************************************
182 * FindCloseChangeNotification (KERNEL32.247)
184 BOOL32 WINAPI FindCloseChangeNotification( HANDLE32 handle)
186 return CloseHandle( handle );